2017-01-03 51 views
0

假设在单线程应用中,我已创建了一个服务器和连接与像以下新的连接到达信号的槽,单线程应用QT时隙执行哪个线程

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 :(

+0

我不太明白这个问题:你说你有一个单线程应用程序。如在:只有一个线程。询问插槽执行的线程是奇怪的:只有一个线程,您已经知道插槽将执行的线程! –

+0

@ KubaOber,我想不管事件循环总是在处理中。这就是为什么我很好奇,如果主线程不可用于处理那么谁是它。 – Tahlil

+0

您需要提出一个更基本的问题:您为什么认为信号和时隙与事件循环有什么关系?在你的情况下,信号插槽连接**完全像**使用函数指针。插槽在信号的主体内被调用。当信号返回时(这只是一种方法,毕竟),插槽已被调用。没有任何事件循环出现。事件循环用于提供跨线程/排队插槽调用,但是你没有这样做。 –

回答

2

主线程。

既然你正在运行单线程应用程序,一切都会有处理(新手除了一些基本级别的IO)

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

每个标准QThread都有自己的事件队列。既然你有一个单线程应用程序,你的事件队列也将在主线程中运行。

在您的长时间运行循环期间结束时,不会有事件处理,也不会处理新的连接。

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

  1. 在大多数的讨论,但仍适用于没有处理信号长时间运行的操作有点失宠/他们的计算过程中的事件是继承QThread和重新实现run()功能。

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

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

所有的选项都是有效的,但在实现上稍有不同。有关更多详细信息,请参阅文档:http://doc.qt.io/qt-5/thread-basics.html

+0

非常感谢您的回答。如果我理解正确,如果一个线程空闲,那么它的事件循环将在工作?在我的场景中,事件循环将不会执行任何操作,即使有新的连接也不会执行该插槽。 – Tahlil

+0

由于您的循环阻塞了线程,因此您将没有事件处理。所以是的,你不会到达事件循环。您的连接处理由调用您的插槽的事件循环完成。一旦你从插槽返回,事件处理将继续。 –

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