gpt4 book ai didi

c++ - 用 QT 线程解决运行时问题

转载 作者:行者123 更新时间:2023-11-30 03:58:50 25 4
gpt4 key购买 nike

我当前的问题是两个 QT 线程。其中之一发出信号以在第二个线程中开始操作,然后等待结果。一旦第二个线程完成,第一个线程应使用第二个线程的结果继续其自己的操作。

为了让第一个线程休眠,我使用了 QMutex 和 QWaitCondition。第一个线程发出一个信号,然后在等待状态下休眠。但现在的问题是:如果第二个线程设法比第一个线程快,并且在第一个线程进入等待条件之前发出 wakeAll() 调用,我就会卡住。我可以实现一个等待时间,但是我又不灵活了,如果第二个线程需要比第一个线程等待更多的时间,我又遇到了问题。

此问题已在此处解决:http://woboq.com/blog/qwaitcondition-solving-unavoidable-race.html , 但他们决定不解决这个问题。那么,是否有可能避免这种竞争条件?

补充:我不想将这个函数转换为第一个线程的函数,因为这个特定的函数应该可以同时从多个线程访问,而不会导致竞争条件。 IE。 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”的子成员(不是直接的,但只能通过它访问)。步进 Controller 外部控件可由多个函数使用,不仅是 Spectrometer_Control 中的函数 moveStepper,但为了简化操作,我只添加了一个外部函数。但是在我不想让我的步进器混淆之后,我想如上所述限制访问。

最佳答案

让第二个线程发回信号并将等待后的代码移到那个插槽可能是安全的。

class Worker1: public QObject{
Q_OBJECT

//...

signals:
void startWorking();
slots:
void answer(QVariant);
};

class Worker2: public QObject{
Q_OBJECT

//...

slots:
void startWorking();
signals:
void answer(QVariant);
};

否则你需要有一个变量,第二个线程在持有 QMutex 时设置为第一个线程发送信号:

线程 1:

emit startWorking();
{
QMutexLocker lock(&thread2->mutex);
while(!thread2->finished){//loop guards against spurious wakeups
thread2->cond->wait(&mutex);
}
}

和线程2:

{
QMutexLocker lock(&mutex);
finished=true;
cond->wakeAll();
}

那样的话,如果线程 2 更快,则在线程 1 到达时 thread2->finished 已经为真,并且互斥锁会在测试它和等待 QWaitCondition 之间保护变量.

关于c++ - 用 QT 线程解决运行时问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27248498/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com