标题问题可能不是很明确。我在Windows7上使用Qt 5。
在线程(QThread)中的某个时刻,在"process()"
函数/方法中,我必须等待属于我在该线程中使用的QSslSocket的"encrypted()"
SIGNAL。另外,我想我应该使用QTimer并等待"timeout()"
信号,以避免在无限循环中被阻塞...
我现在拥有的是:
// start processing data
void Worker::process()
{
status = 0;
connect(sslSocket, SIGNAL(encrypted()), this, SLOT(encryptionStarted()));
QTimer timer;
connect(&timer, SIGNAL(timeout()), this, SLOT(timerTimeout()));
timer.start(10000);
while(status == 0)
{
QThread::msleep(5);
}
qDebug("Ok, exited loop!");
// other_things here
// .................
// end other_things
emit finished();
}
// slot (for timer)
void Worker::timerTimeout()
{
status = 1;
}
// slot (for SSL socket encryption ready)
void Worker::encryptionStarted()
{
status = 2;
}
很明显这行不通。它会永远留在while循环中
所以问题是有办法解决这个问题吗?我怎样才能等待那个"encrypted()"
信号,但不要超过-比方说10秒-以避免陷入等待循环/线程?
5条答案
按热度按时间l7mqbcuq1#
您可以使用本地事件循环来等待信号的发射:
在这里,它会等待,直到
encrypted
被发出或超时到达。6gpjuf902#
从Qt 5.0开始,QSignalSpy提供了一个wait方法。你把它连接到一个信号上,wait()将阻塞,直到信号触发。
kxxlusnw3#
在异步编程中,“等待”被认为是一种反模式。与其等待,不如设计代码来对条件的满足做出React。例如,将代码连接到信号。
实现这一点的一种方法是将您的操作分割成单独的状态,并在进入每个状态时执行一些工作。当然,如果工作量很大,请使用单独的插槽而不是lambda来保持内容的可读性。
请注意,没有显式内存管理。使用指向Qt类的拥有指针是一种过早的优化,应该避免不必要的地方。对象可以是
Worker
(或其PIMPL)的直接成员。子对象必须是所有权层次结构的一部分,其根为
Worker
。这样,您就可以安全地将Worker
示例移动到另一个线程,它使用的对象将跟随它。当然,您也可以在正确的线程中示例化Worker
-有一个简单的idiom。线程的事件调度器拥有工作线程,因此当线程的事件循环退出时(即调用QThread::quit()
)后,worker将自动被释放,不会有资源泄漏。工人的实现:
然后:
请注意,连接到
QThread::started()
将是活泼的:事件调度器不存在,直到QThread::run()
中的某些代码有机会执行。因此,我们必须等待线程通过yielding到达那里--这很可能使工作线程在一两个yields内前进足够远。所以不会浪费太多时间。omhiaaxx4#
我这几天有时间做了些调查...
我浏览了“http://doc.qt.io/qt-5/qsslsocket.html”,发现了这个:
真实的惭愧,我以前没注意到...:(
绝对需要买一些眼镜(* 不幸的是 *,这不是一个笑话!)
我愿意相应地修改我的代码以测试它(星期一@ office)。
很有可能会成功。
[后期编辑]:
是的,这是我在最终代码中实现的解决方案,效果很好,所以我决定分享:)
snz8szmq5#
QSignalSpy是最干净的方式