QT两个子线程之间通过信号-槽通信

假设两个子线程A、B均是通过继承Object类然后使用官方推荐的moveToThread方式创建的。B线程中的work函数内有个while大循环,在里面不断的轮询做某事。
while(running == true)
{
//do something
}

QThread* threadObjThreadA = new QThread();
threadObjA = new ScanThreadObj(NULL);
threadObjA ->moveToThread(threadObjThreadA );

QThread* threadObjThreadB = new QThread();
threadObjB = new ScanThreadObj(NULL);
threadObjB ->moveToThread(threadObjThreadB );

使用以下代码,绑定A中的信号与B中的槽,却发现B中的槽根本无法触发执行信号处理内容。

//两个子线程通过‘信号--槽’单向交互 (A线程--->B线程)
connect(threadObjA , SIGNAL(Sig_exceptionMsg(int)), threadObjB , SLOT(Slot_ProcessException(int)));

解决方法如下:

connect(threadObjA , SIGNAL(Sig_exceptionMsg(int)), threadObjB , SLOT(Slot_ProcessException(int)),Qt::DirectConnection);

说明:要想在子线程A里面触发的信号的槽函数在子线程B执行,信号槽连接必须使用DirectConnection 方式;

Qt::DirectConnection直接连接:相当于直接调用槽函数,但是当信号发出的线程和槽的对象不在一个线程的时候,则槽函数是在发出信号的线程中执行的。

通过打印信号发出线程的ThreadID与槽函数执行线程的ThreadID,发现二者是相等的。

猜的的原因是:
线程B中有自己的while(flag)循环,根本没有机会去执行自己的事件处理。所以压根不会处理到slot函数。线程A的信号发送了,但是B线程中槽函数不能触发,线程B一直阻塞在while中。
根本原因是:接收到信号,但是没空去处理

只有使用DirectConnection 方式,使线程A在发射信号后,直接跨线程调用槽函数,也就是说槽函数依然在线程A中被执行。

对于两个子线程通过‘信号–槽’单向交互 (A线程—>B线程)这种问题,个人建议采取全局变量或者其他中间媒介的方式进行。当然,使用这种方式也可以。但是槽函数实际是在信号发出线程中被执行的。

如果想让槽函数就在B线程中得到执行,那么该如何去做呢?
这个时候只需要在子线程B的work函数的while内加入QCoreApplication::processEvents();
该函数的作用是让程序处理那些还没有处理的事件,然后再把使用权返回给调用者

while(running == true)
{
QCoreApplication::processEvents();
//do something
}

加上QCoreApplication::processEvents()之后,自然也就无需Qt::DirectConnection的连接方式了,也就真正意义上实现了多线程通信。

  • 15
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

thequitesunshine007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值