Does QThread::quit() discard all events in EventQu

2019-07-23 12:37发布

There is main function:

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    Worker w;
    QObject::connect(&w, SIGNAL(done()), &a, SLOT(quit()), Qt::QueuedConnection);
    w.start();

    int ret = a.exec();
    w.quit();
    w.wait();

    return ret;
}

And there is Worker's definition:

class Worker : public QThread
{
    Q_OBJECT
public:
    Worker(QObject *parent=0);
protected:
    void run();
protected slots:
    void process_request();
private:
    int ttl;
    Messenger* messenger;
}

Worker::Worker(QObject * parent)
    :QThread(parent),
    ttl(5),
    messenger(new Messenger(this))
{
    moveToThread(this);
    connect(messenger, SIGNAL(new_message()), SLOT(process_request()), Qt::QueuedConnection);
}

void Worker::finish(){
  quit();
  messenger->disconnectFromNetwork();   
}

void Worker::run(){
  messenger->connectToNetwork("somewhere");
  exec();
  emit done();
}

void Worker::process_request(){
    net_message msg;
    messenger->recv(msg);

    // PROCESSING

    messenger->send(msg);

    BOOST_LOG_SEV(file_log, severity::notification) << "TTL = " << ttl;
    if (--ttl == 0) {
        finish();
    }
}

Well, sorry for the long exposition. The idea was that the Messenger lives in the main thread, and pokes the Worker when it has a new message for it, and the Worker lives only a certain amount of messages, after which it stops and shuts down entire application.

But there is a problem: the log file has lines TTL = -1, and TTL = -2, and such. It shouldn't, and the only reason I can think about is that quit() doesn't quite ends the event loop: it allows pending events to be processed before returning from exec(). Is it so? If "no", then what may cause such a behaviour?

1条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-07-23 12:58

First of all "You're doing that wrong".

Secondly documentation doesn't say what is the state of queue in event loop after exit was called. It is possible that exec() returns after event queue is empty to make sure that all asynchronous cleanups are done (in case if this it top most event loop, in this case it is).


edit:
I've checked source code. Apparently QEventLoop::processEvents is call between each check that event loop should exit. So it looks like exec() returns only when queue is empty.

查看更多
登录 后发表回答