gpt4 book ai didi

c++ - Qt:调用 QEventLoop::exec 后死锁

转载 作者:太空宇宙 更新时间:2023-11-04 13:46:56 24 4
gpt4 key购买 nike

我有一个相当简单的应用程序,当我调用 QEventLoop::exec 时,它似乎在某些情况下死锁。应用程序在两种情况下调用此函数:

  • 当某些数据到达套接字时
  • 根据计时器事件

在这两种情况下,它都用于以下上下文(只是一个 http 查询,实际上没什么特别的):

QNetworkReply::NetworkError HttpGetMessagesStrategy::syncHttp(const QUrl url, QByteArray &dst) const
{
QNetworkRequest request(url);
request.setRawHeader("Cache-Control", "no-cache");

QNetworkAccessManager mgr;
QEventLoop eventLoop;
QObject::connect(&mgr, SIGNAL(finished(QNetworkReply *)), &eventLoop, SLOT(quit()));
QNetworkReply *reply = mgr.get(request);
if (reply == NULL) {
return QNetworkReply::UnknownNetworkError;
}

eventLoop.exec();

QNetworkReply::NetworkError error = reply->error();
if (error == QNetworkReply::NoError) {
dst += reply->readAll();
}
delete reply;

return error;
}

这是它尝试调用它时发生的情况:

...    
#56 0x0000003404b57cdc in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib64/libQtCore.so.4
#57 0x0000003404b804a2 in ?? () from /usr/lib64/libQtCore.so.4
#58 0x0000003404b7d928 in ?? () from /usr/lib64/libQtCore.so.4
#59 0x00000033fba38f0e in g_main_context_dispatch () from /lib64/libglib-2.0.so.0
#60 0x00000033fba3c938 in ?? () from /lib64/libglib-2.0.so.0
#61 0x00000033fba3ca3a in g_main_context_iteration () from /lib64/libglib-2.0.so.0
#62 0x0000003404b7d5f3 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQtCore.so.4
#63 0x0000003404b56722 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQtCore.so.4
#64 0x0000003404b569ec in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQtCore.so.4
#65 0x00007f41c1b4eec7 in HttpGetMessagesStrategy::syncHttp (this=<value optimized out>, url=<value optimized out>, dst=...) at HttpGetMessagesStrategy.cpp:49
#70 0x000000000040e57c in DevicePlugin::timerEvent (this=0x1267390, event=0x7fff902bb5f0) at DevicePlugin.cpp:250
#71 0x0000003404b6698e in QObject::event(QEvent*) () from /usr/lib64/libQtCore.so.4
#72 0x0000003404b57cdc in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib64/libQtCore.so.4
...

正如我们所看到的,它没有等待 HTTP 请求的响应,而是选择了另一个事件并开始处理它。结果,在我的应用程序停止之前,我在当前线程中获得了大量的帧 (746),然后我看到这样的行:

#0  0x00000033faa0efe0 in __pause_nocancel () from /lib64/libpthread.so.0
#1 0x00000033faa0917b in __pthread_mutex_lock_full () from /lib64/libpthread.so.0
#2 0x0000003404a702a3 in ?? () from /usr/lib64/libQtCore.so.4
#3 0x0000003404a6cd95 in QMutex::lock() () from /usr/lib64/libQtCore.so.4
#4 0x0000003404b57952 in QCoreApplication::postEvent(QObject*, QEvent*, int) () from /usr/lib64/libQtCore.so.4
#5 0x000000000040e293 in DevicePlugin::destroyConnection (this=0x1267390, c=0x1a85fb0) at DevicePlugin.cpp:194
#6 0x000000000040e5b6 in DevicePlugin::timerEvent (this=0x1267390, event=0x7fff902b9230) at DevicePlugin.cpp:254
#7 0x0000003404b6698e in QObject::event(QEvent*) () from /usr/lib64/libQtCore.so.4
#8 0x0000003404b57cdc in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib64/libQtCore.so.4
...

谁能解释一下我在这里做错了什么?

最佳答案

http://qt-project.org/doc/qt-4.8/qeventloop.html#exec

int QEventLoop::exec ( ProcessEventsFlags flags = AllEvents ) Enters the main event loop and waits until exit() is called. Returns the value that was passed to exit().

exec() 是 QT 事件处理的表示,在当前线程返回 exit() 之前始终是阻塞调用。这允许主循环 exec() 之外的线程使用 QT 信号和插槽而不会发生冲突。

您应该将您的 finished() 调用连接到您的头文件中定义的您自己的处理插槽。

如果您想使用信号和槽并使用 QOBJECT Makro,请不要忘记从 QObject(或任何其他 QT 对象)继承每个类。

关于c++ - Qt:调用 QEventLoop::exec 后死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25454330/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com