我有一個線程阻塞,直到從系統資源(如USB設備)接收數據。我選擇這個模型是因爲數據量可能會有所不同,並且可能隨時收到數據。在退出應用程序時,我收到消息「QThread:線程仍在運行時銷燬」。我應該如何去關閉這些線程?Qt - 系統級調用阻塞的QThreads
我看了其他問題/解決方案,如:
- 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
第一個解決方案包括使用標誌(包括在我的代碼),但是我的線程將從來沒有達到國旗檢查。 第二個解決方案使用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
爲什麼不使用Qt自己的IO函數,如QFile等?他們使用信號和插槽,所以你只能看'bytesReadyRead'信號。 – sashoalm
@satuon我正在製作我自己的QIODevice,它可以讀寫HID設備。雖然這在我以前從未發生過,但也許可以使用QFile來訪問這些設備。我會試試看,謝謝。 – Daniel
順便說一句,你可以通過縮短和簡化來改善你的問題 - 我讀了不到10%,因爲它太長了。你也應該只發布代碼的相關部分,而不是整個文件。 – sashoalm