USB デバイスなどのシステム リソースからデータを受信するまでブロックするスレッドがあります。このモデルを選択したのは、データの量が変動する可能性があり、いつでもデータを受信できる可能性があるためです。アプリケーションを終了すると、「<strong>QThread: Destroyed while thread is still running」というメッセージが表示されます。これらのスレッドを閉じるにはどうすればよいですか?
次のような他の問題/解決策を見てきました。
- http://www.qtcentre.org/threads/14429-Loop-inside-Qthread-causes-quot-QThread-Destroyed-while-thread-is-still-running-quot
- http://www.qtcentre.org/threads/6211-QThread-Destroyed-while-thread-is-still-running
最初の解決策では、フラグ (コードに含まれています) を使用しますが、スレッドはフラグ チェックに到達しません。2 番目の解決策は QWaitCondition を使用しますが、最初の解決策と同じように見えます。
以下のコードの簡素化されたバージョンを含めました。システム コールの WaitForSingleObject() は、私が実際に使用しているもの (GetOverlappedResult()) の代わりです。
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include <QObject>
#include <QThread>
#include <QReadWriteLock>
#include <QDebug>
#ifdef Q_OS_WIN
#include <windows.h>
#endif // Q_OS_WIN
#ifdef Q_OS_LINUX
#include <unistd.h>
#endif // Q_OS_LINUX
////////////////////////////////////////////////
//
// Worker Object
//
////////////////////////////////////////////////
class Worker : public QObject {
Q_OBJECT
public:
QReadWriteLock lock;
bool running;
public slots:
void loop() {
qDebug() << "entering the loop";
bool _running;
forever {
lock.lockForRead();
_running = running;
lock.unlock();
if (!_running) return;
qDebug() << "loop iteration";
#ifdef Q_OS_WIN
HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL);
WaitForSingleObject(event, INFINITE);
#endif // Q_OS_WIN
#ifdef Q_OS_LINUX
read(0, 0, 1);
#endif // Q_OS_LINUX
}
}
};
////////////////////////////////////////////////
//
// Controller
//
////////////////////////////////////////////////
class Controller {
public:
Controller() {
myWorker.connect(&myThread, SIGNAL(started()), &myWorker, SLOT(loop()));
myWorker.moveToThread(&myThread);
myThread.start();
}
~Controller() {
// Safely close threads
myWorker.lock.lockForWrite();
myWorker.running = false;
myWorker.lock.unlock();
myThread.quit();
//myThread.wait();
//myThread.exit();
//myThread.terminate();
}
private:
QThread myThread;
Worker myWorker;
};
#endif // CONTROLLER_H