我目前的問題是有兩個QT線程。其中之一發出一個信號在第二個線程中開始一個操作,然後等待結果。一旦第二個線程完成,第一個線程應該繼續使用第二個線程的結果進行自己的操作。解決QT線程運行時問題
爲了讓第一個線程睡眠,我使用QMutex和QWaitCondition。第一個線程發出信號,然後在等待狀態下休眠。但現在的問題是:如果第二個線程設法比第一個線程更快,並且在第一個線程進入等待條件之前發出wakeAll() - 調用,我會卡住。我可以實現一個等待時間,但之後我又不靈活了,如果第二個線程需要比第一個線程等待更多的時間,我再次遇到問題。
這個問題已經在這裏解決:http://woboq.com/blog/qwaitcondition-solving-unavoidable-race.html,但他們決定不解決這個問題。那麼,是否有可能避免這種競爭條件?
此外:我不想將此函數轉換爲第一個線程的函數,因爲此特定函數應該可以從多個線程一次訪問而不會導致競爭條件。即Thread1應該調用Thread2中的函數,等到它完成後,Thread3也想調用該函數,但不允許這樣做,它也必須等到完成。如果功能完成,Thread3可以訪問它。 (同樣不止兩個線程)。
實例功能:
這個功能應該發出信號,之後等待喚醒信號:
void Spectrometer_Control::moveStepper(int steps, bool dir)
{
emit stepperMoving();
qDebug() << "From Spectrometer_Control: Stepper should move in direction " + QString::number(dir) + " from position " + QString::number(MonoPos);
int newTarget = MonoPos + ((dir == true)?(steps):(-1 * steps));
qDebug() << "New target: " + QString::number(newTarget);
emit moveStepperToTarget(steps, dir);
qDebug() << "Locking WaitMutex!";
WaitMutex->lock();
qDebug() << "Waiting for signal!";
WaitForEngine->wait(WaitMutex);
WaitMutex->unlock();
qDebug() << "Finally unlocked!";
}
而這個函數接收呼叫,並且應該喚醒每一個等待功能了:
void Stepper_Control_Worker::moveStepper(int steps, bool dir)
{
waitMutex->lock();
qDebug() << "Motor moved from down below!";
Stepper_Control_Worker::STP[1]->setValue((dir == true)?BlackLib::high:BlackLib::low);
usleep(50000);
Stepper_Control_Worker::STP[0]->setValue(BlackLib::low);
usleep(50000);
for(int i = 0; i < steps; i++)
{
Stepper_Control_Worker::STP[0]->setValue(BlackLib::high);
usleep(50000);
Stepper_Control_Worker::STP[0]->setValue(BlackLib::low);
}
WaitCond->wakeAll();
waitMutex->unlock();
emit StepperMoved(steps, dir);
}
第二個函數是類「stepper_control」的子成員(不是直接訪問,但只能通過訪問)。步進控制器外部控制器可以用於多種功能,不僅是Spectrometer_Control的moveStepper功能,而且爲了使事情更簡單,我只添加了一個外部功能。但是在我不想讓我的步進器感到困惑之後,我想按照上面的描述限制訪問。
爲什麼要使用第二個線程,如果你只是想讓第一個線程休眠並等待第二個線程完成? – TheDarkKnight 2014-12-02 11:42:22
因爲我的第二個線程在另一個類中,所以也應該通過其他幾種方式訪問它。把它放到這個類的函數中,就不可能從其他線程中的其他線程使用它,這些線程也必須等待它。 (AFAIK,這是錯的)? – 2014-12-02 11:45:54
線程不駐留在類中。 QThread更像是一個線程控制器。派生自QObject的類可以移動到不同的線程。無論如何,我仍然不明白爲什麼你需要創建第二個線程。線程允許併發處理,根據你的描述,你的應用程序沒有使用這個。如果您發佈了問題的示例代碼,您可能會收到更好的回覆,並且缺乏這可能是爲什麼有人(而不是我)決定降低您的問題的原因。 – TheDarkKnight 2014-12-02 13:57:08