单线程应用程序qt槽在哪个线程中执行

时间:2017-01-03 04:48:32

标签: multithreading qt event-loop

假设在单线程应用程序中,我创建了一个服务器并连接了一个带有新连接到达信号的插槽,如下所示,

 connect(mTcpServer, SIGNAL(newConnection()), this, SLOT(newClientConnected()));

在这一行之后我进入了一个巨大的循环,在那里我做了一些计算。所以作为主线程的我的单线程忙于循环,现在有一个新的连接到达。

所以我的问题是,

1) In which thread the new slot will be executed? I ask this because
main thread is already executing some code in a loop. 

2) In which thread the event loop is maintained? Because certainly my single
thread is executing some code in a loop and is not maintaining the event loop.

我是QT的新手:(

2 个答案:

答案 0 :(得分:2)

主线。

由于您运行的是单线程应用程序,因此将在那里处理所有内容(基本级别的某些IO除外)。

您的插槽将始终在调用线程中执行,除非您创建Qt::QueuedConnection以在拥有该插槽所属的对象的线程中运行插槽。一旦运行多个线程,这就变得很重要。

每个标准QThread都有自己的事件队列。由于您有一个单线程应用程序,因此您的事件队列也将在主线程中运行。

在长时间运行的循环过程中,不会有事件处理,也不会处理新连接。

解决方案:让您的长时间运行计算在不同的线程中运行,以便继续处理新的连接和事件。这里有不同的选择。

  1. 在大多数讨论中有点失宠,但对于在计算过程中不必处理信号/事件的长时间运行操作仍然有效,可以继承QThread并重新实现run()功能

  2. 将您的计算移动到一个函数中并使用QtConcurrent::run()运行它,它将自动使用一个线程。

  3. 创建QRunnable的子类并使用全局线程池。

  4. 所有选项都有效,但在实施方面略有不同。有关更多详细信息,请参阅文档:http://doc.qt.io/qt-5/thread-basics.html

答案 1 :(得分:0)

  

在哪个线程中维护事件循环?因为肯定是我的单身   线程正在循环中执行某些代码,而不是维护事件循环。

每个线程都可以有一个事件循环。如果您的代码没有将控件返回到它运行的线程中的事件循环,那么您将不会处理任何事件,并且正在为失败做好准备。所以不要这样做。按如下方式转换代码:

// before
forever {
  code();
}

// after
void timerEvent(QTimerEvent *ev) {
  if (ev->timerId() == m_timer.timerId())
    code();
}

void start() {
  m_timer.start(0, this);
}

QBasicTimer m_timer; // class member