根据主循环设置的变量值立即中断辅助线程循环

问题描述 投票:0回答:1

我在 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 循环完成时才更改为运行模式,有人可以帮助我找到一个好的解决方案吗?

谢谢你

我尝试在每一步中打破循环,但速度不够快

c++ multithreading concurrency mutex semaphore
1个回答
0
投票

使用

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;
   }
   ...
}
© www.soinside.com 2019 - 2024. All rights reserved.