为什么从主线程调用插槽?

时间:2010-10-02 04:54:09

标签: multithreading qt qthread

我有一个Qt应用程序,它有两个线程:处理GUI的主线程和管理网络连接的第二个线程。这是线程代码:

void thread::run()
{
    QTcpServer server;

    server.connect(&server,SIGNAL(newConnection()),this,SLOT(OnConnect()));

    //...
}

当我在OnConnect()的开头放置断点并调试应用程序时,它会宣布从主线程调用OnConnect()

如何让OnConnect()在与QTcpServer相同的帖子中运行?

2 个答案:

答案 0 :(得分:4)

为了给出更全面的答案,请深入了解信号槽连接和线程上下文如何相互作用。基本上,对于更多连接(自动连接),如果发射器和接收器都在同一个线程上下文中,则将直接调用插槽,否则它将是一个排队连接,并且插槽将在线程上下文中运行包含插槽的对象。在这种情况下,它必须排队,这意味着您的线程是主应用程序的线程上下文的一部分,而不是它自己的。这由the documentation强化了Qt提供了对其线程的概述,其中它声明QThread实例由创建它的线程上下文“拥有”,而不是它所代表的线程上下文。这意味着您有三个主要选择:

  1. 您可以使用moveToThread()将线程移动到自己的上下文中。请注意,这可能会在删除线程时导致问题,除非您将其移回到将被销毁的上下文中,并且这只能在源线程上下文中完成,因此必须在运行函数退出之前完成。
  2. 您可以将QThread实例视为线程的句柄,而不是作为线程本身的一部分。如果你需要在新线程的上下文中完成的事情,创建一个不同的对象来处理它们,并在新线程的上下文中实例化它们(在run函数内)。这就是我的建议。
  3. 强制直接连接。这意味着你需要确保在插槽中运行的代码是线程安全的,忽略了Qt内置的使这些函数成为线程安全的方法。 This is what you have done

答案 1 :(得分:0)

似乎问题是我没有将Qt::DirectConnection作为connect()的最后一个参数传递。

添加之后,它就可以了。

相关问题