Qt例子,线程间通信,如何在线程外部对线程进行控制,问题请看问题补充,多谢了先

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt例子,线程间通信,如何在线程外部对线程进行控制,问题请看问题补充,多谢了先相关的知识,希望对你有一定的参考价值。

最近在捣腾Qt的多线程,在线程间通信这一块有点疑问,一般而言,使用全局变量或者消息机制来进行线程间通信,这里,得益于Qt的signal/slot机制,我使用使用了信号来通信。

先说一下我对基本概念的理解,从操作系统的角度去看,任一时刻,只能有一个线程在运行,基于这个观点,引出了我的问题。

我有两个线程,线程A和线程B,当A处于运行态的时候,B处于等待态,现在,我在A的运行过程中,想给B传递一些数据,我使用了Qt::DirectConnection来把A的signal连接到B的slot上,而Qt::DirectConnection的说明是直接跳到slot函数去执行slot的代码。现在的问题是,A处于运行态,B处于等待态,并且slot函数属于B线程的,通过Qt::DirectConnection怎么能够跑去执行B线程的代码呢?因为B还在等待,还没轮到B执行,难道是,操作系统先把A挂起,然后唤醒B,接着跑去执行B的slot函数?还是什么机制,因为无论如何,AB是不可能同时处于运行态的,这个Qt::DirectConnection是如何保证B的slot能够马上执行,并且保证代码安全的(而不是一个非法的强制跳转)执行呢?

基于这个问题,我还引出了另外一个问题,如果使用消息机制进行通信,线程A给线程B发送消息只能使用postEvent不能使用sendEvent,postEvent把消息放入B的消息队列中,然后A继续执行,当B运行时,就从消息队列中取出消息进行处理,这样才安全,而sendEvent是马上跑到B的消息处理函数中去处理这个消息,处理完毕后才返回,然后A继续执行,但是这个问题同开始的问题一样,当调用sendEvent时,A处于运行态,B处于等待态,要处理这个消息,必须强制从A跳到B去执行代码,这不是非法的了吗?如果B线程没有唤醒,怎么能够执行B的消息处理函数呢?而B要运行则A必然要挂起,这里就很乱了,难道操作系统会先挂起A,然后唤醒B,B处理完后,又挂起B,再唤醒回A,A从sendEvent返回处开始继续执行。

上面的问题可以简单的概括为,如何在线程外面对线程进行控制,就好比是,在B线程外面(A线程里),对B进行控制,因为一旦处在线程B外面,就表明其他线程(A)在运行态,而本身B线程在挂起,而B没有进入运行态的话,怎么控制得了它的执行序列呢?非常困惑

参考技术A 不要谈什么qt,这个我不懂,但是就谈一谈线程的本质,那都是一样的,2个线程不可能同时进行这个是正确的,但是多核处理器除外。你所说的post和send,我不知道可不可以这么理解,就好象一个是异步,一个是同步。线程A和B肯定都有自己的休息时间,不可能一直执行,要不然那就不叫时间片段了。时间片段和消息,那都是对cpu硬件来说的,具体的转换线程的信号是由cpu处理器完成的。所以说不可能存在B一直休息,然后A去唤醒B的处理函数一说。而应该说B总有休息的时候,也包括运行的时候,那就是根据cpu信号来判断的,他运行的时候,他的消息处理函数总能收到消息,因为消息可以暂时保存在内存中,至于说根据处理函数的决定,然后根据传来时的参数(标名是post还是send)来判断是由当前线程来执行,还是由传来的线程来执行。我是个人理解。你看对不对呢。。本回答被提问者和网友采纳

Java进程间通信和线程间通信?

【中文标题】Java进程间通信和线程间通信?【英文标题】:Java Inter Process communication and Inter Thread communication? 【发布时间】:2010-03-27 01:57:05 【问题描述】:

Java 上下文中的线程和进程有什么区别? Java中如何实现进程间通信和线程间通信? 请指出一些现实生活中的例子。

【问题讨论】:

【参考方案1】:

根本区别在于线程存在于相同的地址空间中,而进程存在于不同的地址空间中。这意味着线程间通信是关于传递对对象的引用和更改共享对象,而进程是关于传递对象的序列化副本。

在实践中,Java 线程间通信可以实现为对共享对象的普通 Java 方法调用,并引入适当的同步。或者,您可以使用新的并发类来隐藏一些本质(且容易出错)的同步问题.

相比之下,Java 进程间通信是基于将状态、请求等转换为可以作为消息或作为流发送到另一个 Java 进程的字节序列的最低级别。您可以自己完成这项工作,也可以使用各种复杂程度不同的“中间件”技术来抽象出实现细节。可能使用的技术包括,Java 对象序列化、XML、JSON、RMI、CORBA、SOAP/“Web 服务”、消息队列等。

在实际层面上,线程间通信比进程间通信快很多数量级,并且可以让您做很多事情变得更简单。但缺点是一切都必须存在于同一个 JVM 中,因此存在潜在的可扩展性问题、安全性问题、健壮性问题等等。

【讨论】:

【参考方案2】:

线程可以访问进程内的内存,甚至是同一进程内的另一个线程可以操作的内存。由于所有线程都在同一个运行进程内部,因此它们可以更快地通信(因为它们不需要操作系统来裁判)。

一个进程不能访问另一个进程内部的内存,尽管您可以通过各种方式在进程之间进行通信,例如:

    网络包。 文件 管道 共享内存 信号量 Corba 消息 RPC 调用

进程间通信要记住的重要一点是,通信必须通过操作系统进行管理,并且像所有需要中间人的事情一样,这会增加开销。

不利的一面是,如果一个线程行为不端,它会在正在运行的进程中这样做,而且它很有可能会取消所有行为良好的线程。如果一个进程行为不端,它不能直接写入其他进程的内存,很可能只有行为不端的进程会死。

【讨论】:

【参考方案3】:

线程间通信 = 同一 JVM 内的线程相互通信

进程间通信 (IPC) = 同一台机器内的线程,但在不同的 JVM 中运行,相互通信

同一 JVM 中的线程可以使用流水线通过无锁队列以纳秒级延迟相互通信。

不同 JVM 中的线程可以使用堆外共享内存(通常通过同一个内存映射文件获取)以纳秒级延迟相互通信。

不同机器中的线程可以使用网络以微秒级的延迟相互通信。

有关无锁队列和 IPC 的完整说明,您可以查看CoralQueue。

免责声明:我是 CoralQueue 的开发者之一。

【讨论】:

【参考方案4】:

我喜欢将 JVM 的单个实例视为一个进程。因此,进程间通信将在 JVM 实例之间进行,例如,通过套接字(消息传递)。

java 中的线程实现 Runnable 并包含在 JVM 中。它们仅通过在 JVM 中传递引用来共享数据。每当线程共享数据时,您几乎总是需要保护数据,以免多个线程相互干扰。有许多保护机制都涉及防止多个线程进入代码的关键部分。

【讨论】:

以上是关于Qt例子,线程间通信,如何在线程外部对线程进行控制,问题请看问题补充,多谢了先的主要内容,如果未能解决你的问题,请参考以下文章

Java进程间通信和线程间通信?

VC++ 进程间的通信

Java内存模型

[转]QT子线程与主线程的信号槽通信-亲测可用!

多线程-线程间的通信

多线程-线程间的通信