3

main功能:

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;
}

还有Worker的定义:

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();
    }
}

好吧,对于冗长的说明感到抱歉。这个想法是 Messenger 存在于主线程中,当它有新消息时会戳 Worker,而 Worker 只存在一定数量的消息,之后它会停止并关闭整个应用程序。

但是有一个问题:日志文件有行TTL = -1,和TTL = -2,等等。它不应该,我能想到的唯一原因是它quit()并没有完全结束事件循环:它允许在从exec(). 是这样吗?如果“否”,那么可能导致这种行为的原因是什么?

4

1 回答 1

7

首先“你做错了”

其次,文档没有说明调用退出后事件循环中队列的状态是什么。有可能exec()在事件队列为空后返回以确保完成所有异步清理(如果这是最顶层的事件循环,在这种情况下是)。


编辑:
检查了源代码。显然QEventLoop::processEvents是在每次检查事件循环应该退出之间调用。所以看起来exec()只有当队列为空时才返回。

于 2012-12-03T14:40:25.817 回答