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

Start and Stop a loop within a Thread in C++

本文关键字:线程 循环 C++ 启动      更新时间:2023-10-16

我需要从一个事件开始一个循环,然后从另一个事件停止它。我的想法是在按下按钮时调用函数 startDequeuing(),以便带有循环的线程启动,然后终止此循环,将"脱行"变量从函数 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();
    }
}

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

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

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

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

dequeing定义为原子布尔值:

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

它比使用互斥锁快得多,并且可以为您提供相同的同步。