2

我需要从一个事件开始一个循环,然后从另一个事件中停止它。我的想法是当我按下按钮时调用函数 startDequeuing(),以便启动具有循环的线程,然后终止该循环,将函数 stopDequeuing() 中的“出队”变量设置为 false。

这是我第一次使用线程,当我启动循环时程序会锁定,我认为是因为变量“出队”被锁定并且无法从线程外部访问,对吗?

我怎么解决这个问题??

这里有一些代码:

void CameraManager::startDequeuing(){
    dequeuing = true;
    std::thread dequeueThread(&CameraManager::dequeueLoop, this);
    dequeueThread.join();
}

void CameraManager::stopDequeuing(){
    dequeuing = false;
}

void *CameraManager::dequeueLoop(){
    while(dequeuing){
        highSpeedCamera->dequeue();
        highSpeedCamera->enqueue();
    }
}
4

3 回答 3

3

使用线程的全部意义在于让多个函数并行运行。这里:

std::thread dequeueThread(&CameraManager::dequeueLoop, this);
dequeueThread.join();

您启动第二个线程并使第一个线程进入睡眠状态,等待生成的线程返回。所以你仍然只有一个线程在运行。如果您有这种 GUI 事件循环,您可能会锁定添加回调的可能性,当该事件循环为空时,该回调将被调用。这可能使您可以在不使用线程的情况下做您想做的事情。

解决方案可能如下所示:

void CameraManager::startDequeuing(){
    dequeuing = true;
    dequeueThread = std::thread(&CameraManager::dequeueLoop, this);
}

void CameraManager::stopDequeuing(){
    {
        std::lock_guard<std::mutex> lock( mutex );
        dequeuing = false;
    }
    dequeueThread.join();
}

bool CameraManager::keepOnDequeuing()
{
    std::lock_guard<std::mutex> lock( mutex );
    return dequeuing;
}

void *CameraManager::dequeueLoop(){
    while( keepOnDequeuing() ){
        highSpeedCamera->dequeue();
        highSpeedCamera->enqueue();
    }
}
于 2012-08-17T14:50:11.473 回答
3

你的程序死锁因为join()会阻塞直到你的线程函数完成;并且它永远不会在那个时候完成,因为它正在有效地执行while(true)

你想dequeueThread成为你班级的一员。为什么您希望它仅在 范围内生存startDequeuing

于 2012-08-17T14:50:43.157 回答
3

定义dequeing为原子布尔值:

#include <atomic>
std::atomic_bool dequeing = false;

它比使用互斥锁要快得多,并且可以获得相同的同步。

于 2012-08-17T21:03:03.547 回答