0

いくつかのスレッドでアプリケーションを実行しました。stopConsumer内部で keypressedEventを呼び出すと、すべてが正常に機能するようです。しかし、closeEvent のデストラクタ内で呼び出すと、失敗します。

次のような run メソッドを持つ QThread クラス:

void Consumer::run()
{
    forever {

        // do something something
        // do something something
        // do something something


        //-------------------------------- check for abort
        abortMutex.lock();
        if(abort) {
            abortMutex.unlock();
            qDebug() << "abort..";
            break;
        } abortMutex.unlock();
        //-------------------------------- check for abort
    }
    qDebug() << "Consumer > emit finished()";
    emit finished();
}

void Consumer::stopConsume() {
    abortMutex.lock();
    abort = true;
    abortMutex.unlock();
}

および MainWindow のメソッド:

void initConsumers()
{
    consumer1 = new Consumer(....);

    connect(consumer1, SIGNAL(finished()),
            this, SLOT(deleteConsumer()));

    consumer1->start();
}

void stopConsumer() {
    if(consumer1!=NULL) {
        qDebug() << "stopConsumer";
        consumer1->stopConsume();
    }
}

呼び出すキーが押された場合stopConsumer..大丈夫ですdeleteConsumer。到達しました。

stopConsumerMainWindow デストラクタ内または MainWindow 内で呼び出すcloseEventと、スロットdeleteConsumerに到達することはありません。

何か案は?

4

2 に答える 2

2

Consumerクラスとあなたのスレッド アフィニティMainWindow異なる場合、内部への呼び出しは を使用している可能性が高く、スロットがすぐに呼び出されないことを意味します。connectinitConsumers()Qt::QueuedConnectiondeleteConsumer()

コンシューマがメイン ウィンドウのデストラクタから (または、同等のクローズ イベントから) 確実に削除されるようにしたい場合、考えられる解決策の 1 つはstopConsume()、コンシューマを呼び出し、スレッドが実行されなくなるまで待機することです ( httpを参照)。 ://qt-project.org/doc/qt-5.1/qtcore/qthread.html#isRunning )、直接呼び出しdeleteConsumer()ます。

アップデート

上記で説明した例を次に示します。

consumer1->stopConsume();
consumer1->wait();
deleteConsumer();

接続タイプを に切り替えることはお勧めできません。これQt:DirectConnectionにより、deleteConsumer()関数が の本体から呼び出され、Consumer::run()アプリケーションがクラッシュする可能性があります。

于 2013-08-22T19:00:14.080 に答える