我有一个用Qt编写的简单客户端服务器程序,其中进程使用MPI进行通信。我试图实现的基本设计如下:
第一个进程(“服务器”)启动一个GUI(派生自QMainWindow
),它监听来自客户端的消息(使用repeat fire QTimer
和异步MPI接收调用),根据收到的消息更新GUI,并向每条消息发送回复。
每个其他进程(“客户端”)都在无限循环中运行,而他们打算做的只是向服务器进程发送消息,接收回复,进入休眠状态一段时间,然后唤醒起来重复一遍。每个进程都实例化从QThread
派生的单个对象,并调用其start()
方法。这些类的run()
方法都是这样的:
来自foo.cpp:
void Foo::run()
{
while (true)
{
// Send message to the first process
// Wait for a reply
// Do uninteresting stuff with the reply
sleep(3); // also tried QThread::sleep(3)
}
}
在客户端的代码中,任何地方都没有调用exec()
,因此不应该启动事件循环。
问题是客户端永远不会从睡眠状态中醒来(如果我用{2}写入日志文件来保持sleep()
调用,只执行第一个,控制永远不会到达第二个。这是因为我没有启动事件循环吗?如果是这样,实现所需功能的最简单方法是什么?
答案 0 :(得分:0)
客户端代码中的某些类可能需要启动事件循环。如果您没有客户端的事件循环并且您已经使用MPI,为什么要为客户端使用QThreads?
答案 1 :(得分:0)
问题的一个问题是 - 睡眠和事件循环无关。
无论是否从线程的被覆盖的run()
函数或任何其他函数调用它,Sleep都会使调用线程保持睡眠状态。它没有任何区别,也没有逃脱。
实际上,如果在exec()
(QThread的默认实现是)中的某处调用run()
,则控件将不会返回给调用者。
如果记录器对象是本地的,或者sleep()
函数始终可用,则第二个日志语句未写入的原因不能与run()
直接相关。在完成指定的睡眠量后,控件必须返回到线程。但同时,线程可能会失去对传入连接等瞬态对象的控制。
也许当问到这个问题时,QThread :: sleep()是一个私有函数。现在使用Qt 5,sleep或msleep或甚至usleep是公共静态函数。