qt多线程的同步问题

今天在写qt程序的过程中遇到了一个问题。我的程序理论上是有两个线程,但实际上完全不是。除了主线程之外我的另一个线程主要的任务是监听一个网络端口,收到数据后以信号的方式发送给主线程,然后主线程在对应的槽函数中处理相应的数据。同时我的主线程还处理了许多按键的槽函数,在按键的槽函数中会弹出一个零时的对话框窗口。我的问题是当我在处理按键槽函数弹出的窗口时(注意此时按键槽函数还没有返回)出现场收到了网络监听线程发给主线程的信号并进入对应的槽函数进行处理,此时程序出现了卡死的现象。对于一个专业的软件工程师,这种情况是绝对不允许发生的。根据多年的多线程编程经验我马上意识到问题所在(就是上面描述的过程)。很明显这是一个很典型的多线程程序中经常遇到的线程同步(临界区)的问题。很明显弹出窗口后的代码是不允许被打断的,我们需要把这部分代码作为临界区代码保护起来。于是我尝试了这种方法,但是这种方法无效。于是我查看了qt的官方文档,我发现了QObject::connect函数的第五个参数的作用:

connect(Sender,SIGNAL(signal),Receiver,SLOT(slot),Qt::DirectConnection);  
第五个参数代表槽函数在哪个线程中执行 :
1)自动连接(AutoConnection),默认的连接方式,如果信号与槽,也就是发送者与接受者在同一线程,等同于直接连接;如果发送者与接受者处在不同线程,等同于队列连接。
2)直接连接(DirectConnection),当信号发射时,槽函数立即直接调用。无论槽函数所属对象在哪个线程,槽函数总在发送者所在线程执行,即槽函数和信号发送者在同一线程
3)队列连接(QueuedConnection),当控制权回到接受者所在线程的事件循环时,槽函数被调用。槽函数在接受者所在线程执行,即槽函数与信号接受者在同一线程
4)锁定队列连接(QueuedConnection)
Qt::BlockingQueuedConnection:槽函数的调用时机与Qt::QueuedConnection一致,不过发送完信号后发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。
5)单一连接(UniqueConnection)
Qt::UniqueConnection:这个flag可以通过按位或(|)与以上四个结合在一起使用。当这个flag设置时,当某个信号和槽已经连接时,再进行重复的连接就会失败。也就是避免了重复连接

所以,根据实际应用场景,我把网络监听线程的信号槽函数使用了QueuedConnection,然后就没有卡死的现象啦。

猜你喜欢

转载自blog.csdn.net/BLUCEJIE/article/details/107856807