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

まず「あなたのやり方は間違っている」

第 2 に、exit が呼び出された後のイベント ループ内のキューの状態がドキュメントに記載されていません。すべての非同期クリーンアップが完了したことを確認するために、イベント キューが空になった後に戻ることができexec()ます (これがイベント ループの一番上にある場合、この場合はそうです)。


編集:ソース コードを確認し
ました。どうやら、イベントループが終了する必要がある各チェックの間に呼び出しがあります。したがって、キューが空の場合にのみ戻るように見えます。QEventLoop::processEventsexec()

于 2012-12-03T14:40:25.817 に答える