在C ++中的Thread中启动和停止循环

时间:2012-08-17 14:44:01

标签: c++ multithreading loops c++11 stdthread

我需要从事件开始循环,然后从另一个事件中停止它。 我的想法是当我按下按钮时调用函数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();
    }
}

3 个答案:

答案 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();
    }
}