代码之家  ›  专栏  ›  技术社区  ›  Nathan Osman

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

  •  1
  • Nathan Osman  · 技术社区  · 15 年前

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

    void thread::run()
    {
        QTcpServer server;
    
        server.connect(&server,SIGNAL(newConnection()),this,SLOT(OnConnect()));
    
        //...
    }
    

    当我在 OnConnect() 并调试应用程序,它宣布 连接() 正在从主线程调用!

    我怎么能 连接() 在同一线程中运行 QTcpServer ?

    2 回复  |  直到 15 年前
        1
  •  4
  •   Community Mohan Dere    8 年前

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

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

    问题似乎是我没有路过 Qt::DirectConnection 作为的最后一个参数 connect()

    加上这一点,它起作用了。