我在 C++ 中遇到并发问题,正在努力寻找最佳解决方案。我有两个线程:一个是主程序,另一个负责控制设备的灯光。这是我的第二个线程的代码:
void DroneService::setUpLightsMode(LightModes mode){
this->lightMode = mode;
k_work_submit(&work_queue);
}
void DroneService::workHandler(struct k_work* work){
DroneService* droneService = getInstance();
while(droneService->lightMode == Stop){
droneService->rightLed->syncFadeLed(100, 10, 3000);
k_msleep(1000);
droneService->rightLed->syncFadeLed(10, 100, 3000);
k_msleep(1000);
}
if (droneService->lightMode == Running && droneService->pastLightMode != Running){
LOG_DBG("*************Running\n");
droneService->pastLightMode = Running;
droneService->rightLed->syncFadeLed(10, 100, 500);
}
}
可以看到我的主线程通过变量lightMode修改了第二个线程需要工作的模式,但是我需要能够在lightMode变为Running状态时立即中断循环。目前,这种情况不会发生,因为 while 循环需要几秒钟的时间,并且只有在 while 循环完成时才更改为运行模式,有人可以帮助我找到一个好的解决方案吗?
谢谢你
我尝试在每一步中打破循环,但速度不够快
使用
std::condition_variable
。这也将保护您的状态变量,但更重要的是,为您提供可以“等待”的东西。或者,就您而言,wait_for
——带有超时的等待调用的变体。因此,您可以 wait_for
状态更改或 1000 毫秒超时,以先到者为准:
std::mutex mutex;
std::condition_variable condition;
LightModes mode=LightModes::stop;
...
while (true)
{
{
std::lock_guard<decltype(mutex)> lock(mutex);
if (mode!=LightModes::stop) break;
}
rightLed->syncFadeLed(100, 10, 3000);
{
std::unique_lock<decltype(mutex)> lock(mutex);
auto result=condition.wait_for(lock, std::chrono::milliseconds(1000), [this]() { return mode!=LightModes::stop; });
if (result==std::cv_status::no_timeout) break;
}
...
}