Multithreading 单线程应用程序qt插槽在哪个线程中执行
假设在一个单线程应用程序中,我创建了一个服务器并用新的连接到达信号连接了一个插槽,如下所示Multithreading 单线程应用程序qt插槽在哪个线程中执行,multithreading,qt,event-loop,Multithreading,Qt,Event Loop,假设在一个单线程应用程序中,我创建了一个服务器并用新的连接到达信号连接了一个插槽,如下所示 connect(mTcpServer, SIGNAL(newConnection()), this, SLOT(newClientConnected())); 在这一行之后,我进入了一个巨大的循环,在那里我做了一些计算。因此,我的单线程(主线程)在循环中忙碌,现在一个新的连接到达 所以我的问题是 1) In which thread the new slot will be executed? I a
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的新手:(主线程)
因为您运行的是单线程应用程序,所以所有的事情都将在那里处理(除了一些基本级别的IO)
插槽将始终在调用线程中执行,除非创建Qt::QueuedConnection
以在拥有插槽的对象所属的线程中运行插槽。这一点在运行多个线程时变得很重要
每个标准的QThread
都有自己的事件队列。因为您有一个单线程应用程序,所以您的事件队列也将在主线程中运行
这意味着在长时间运行的循环中,将不会有事件处理,也不会处理新连接
解决方案:让长时间运行的计算在不同的线程中运行,以继续处理新的连接和事件。此处为您提供了不同的选项
QThread
子类化并重新实现run()
函数QtConcurrent::run()
运行它,该函数将自动使用线程QRunnable
的子类并使用全局线程池Qt::QueuedConnection
以在拥有插槽的对象所属的线程中运行插槽。这一点在运行多个线程时变得很重要
每个标准的QThread
都有自己的事件队列。因为您有一个单线程应用程序,所以您的事件队列也将在主线程中运行
这意味着在长时间运行的循环中,将不会有事件处理,也不会处理新连接
解决方案:让长时间运行的计算在不同的线程中运行,以继续处理新的连接和事件。此处为您提供了不同的选项
QThread
子类化并重新实现run()
函数QtConcurrent::run()
运行它,该函数将自动使用线程QRunnable
的子类并使用全局线程池// 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
在哪个线程中维护事件循环?因为我的单线程
线程正在循环中执行某些代码,并且没有维护事件循环
每个线程都可以有一个事件循环。如果您的代码没有将控件返回到它所运行的线程中的事件循环,则您将不会处理任何事件,并将自己设置为失败。因此,不要这样做。请按以下方式转换代码:
// 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
非常感谢你的回答。如果我理解正确,如果一个线程是空闲的,那么它的事件循环将工作?在我的场景中,事件循环将不做任何事情,即使有一个新的连接,它也不会执行插槽。因为你的循环阻塞了线程,你将没有事件处理。所以,是的,你不会到达事件循环。哟您对连接的处理是由调用插槽的事件循环完成的。一旦您从插槽返回,事件处理将继续。非常感谢您的回答。如果我理解正确,如果一个线程只有空闲,那么它的事件循环才会工作?在我的场景中,事件循环将不起任何作用,即使有一个新的连接,它也不会工作不会执行插槽。由于您的循环正在阻塞线程,因此您将没有事件处理。因此,是的,您将不会到达事件循环。您的连接处理由调用插槽的事件循环完成。一旦您从插槽返回,事件处理将继续。我不太理解这个问题:您说您有一个已读应用程序。如中所示:只有一个线程。询问插槽将在哪个线程上执行很奇怪:只有一个线程,您已经知道插槽将在哪个线程中执行!@KubaOber,我认为无论以何种方式,事件循环总是在被处理。这就是为什么我很好奇,如果主线程不可用于该处理,那么en是谁做的。你需要问一个更基本的问题:为什么你认为信号和插槽必然与事件循环有关?在你的例子中,信号插槽连接就像使用函数指针。插槽是从信号体内部调用的。当信号返回时(它只是一个