我需要从事件开始循环,然后从另一个事件中停止它。 我的想法是当我按下按钮时调用函数startDequeuing(),以便循环启动一个线程然后终止这个循环放置" dequeuing"来自函数stopDequeuing()的变量为false。
这是我第一次使用线程时,程序会在我启动循环时锁定,我认为因为变量' dequeuing'从线程外部被锁定且无法访问,我是否正确?
我该如何解决这个问题?
这里有一些代码:
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();
}
}
答案 0 :(得分:3)
您的程序死锁,因为join()
将阻塞,直到您的线程函数完成;它永远不会在那时完成,因为它有效地执行while(true)
。
您希望dequeueThread
成为您班级的成员。为什么你希望它只能在startDequeuing
范围内生存?
答案 1 :(得分:3)
将dequeing
定义为原子布尔:
#include <atomic>
std::atomic_bool dequeing = false;
它比使用互斥锁快得多,并且可以获得相同的同步。
答案 2 :(得分:2)
使用线程的关键是获得多个并行运行的函数。这里:
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();
}
}