我目前的问题是有两个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