C++ 将std::condition_变量与原子<;布尔>;
关于如何处理原子,以及如何处理std::condition_变量,有几个问题。但我的问题是,我下面的用法是否正确 三个线程,一个ctrl线程在取消暂停另外两个线程之前执行准备工作。ctrl线程还能够在工作线程(发送方/接收方)处于紧密的发送/接收循环时暂停它们。 使用原子的想法是,如果没有设置暂停的布尔值,则使紧循环更快C++ 将std::condition_变量与原子<;布尔>;,c++,multithreading,c++11,C++,Multithreading,C++11,关于如何处理原子,以及如何处理std::condition_变量,有几个问题。但我的问题是,我下面的用法是否正确 三个线程,一个ctrl线程在取消暂停另外两个线程之前执行准备工作。ctrl线程还能够在工作线程(发送方/接收方)处于紧密的发送/接收循环时暂停它们。 使用原子的想法是,如果没有设置暂停的布尔值,则使紧循环更快 class SomeClass { public: //...
class SomeClass
{
public:
//...
// Disregard that data is public...
std::condition_variable cv; // UDP threads will wait on this cv until allowed
// to run by ctrl thread.
std::mutex cv_m;
std::atomic<bool> pause_test_threads;
};
void do_pause_test_threads(SomeClass *someclass)
{
if (!someclass->pause_test_threads)
{
// Even though we use an atomic, mutex must be held during
// modification. See documentation of condition variable
// notify_all/wait. Mutex does not need to be held for the actual
// notify call.
std::lock_guard<std::mutex> lk(someclass->cv_m);
someclass->pause_test_threads = true;
}
}
void unpause_test_threads(SomeClass *someclass)
{
if (someclass->pause_test_threads)
{
{
// Even though we use an atomic, mutex must be held during
// modification. See documentation of condition variable
// notify_all/wait. Mutex does not need to be held for the actual
// notify call.
std::lock_guard<std::mutex> lk(someclass->cv_m);
someclass->pause_test_threads = false;
}
someclass->cv.notify_all(); // Allow send/receive threads to run.
}
}
void wait_to_start(SomeClass *someclass)
{
std::unique_lock<std::mutex> lk(someclass->cv_m); // RAII, no need for unlock.
auto not_paused = [someclass](){return someclass->pause_test_threads == false;};
someclass->cv.wait(lk, not_paused);
}
void ctrl_thread(SomeClass *someclass)
{
// Do startup work
// ...
unpause_test_threads(someclass);
for (;;)
{
// ... check for end-program etc, if so, break;
if (lost ctrl connection to other endpoint)
{
pause_test_threads();
}
else
{
unpause_test_threads();
}
sleep(SLEEP_INTERVAL);
}
unpause_test_threads(someclass);
}
void sender_thread(SomeClass *someclass)
{
wait_to_start(someclass);
...
for (;;)
{
// ... check for end-program etc, if so, break;
if (someclass->pause_test_threads) wait_to_start(someclass);
...
}
}
void receiver_thread(SomeClass *someclass)
{
wait_to_start(someclass);
...
for (;;)
{
// ... check for end-program etc, if so, break;
if (someclass->pause_test_threads) wait_to_start(someclass);
...
}
class-SomeClass
{
公众:
//...
//忽略数据是公开的。。。
std::condition_variable cv;//UDP线程将在此cv上等待,直到允许为止
//通过ctrl线程运行。
std::mutex cv_m;
std::原子暂停测试线程;
};
void do_pause_test_线程(SomeClass*SomeClass)
{
如果(!someclass->暂停测试线程)
{
//即使我们使用原子,互斥也必须在
//修改。参见条件变量的文档
//notify_all/wait。实际操作不需要保留互斥
//通知电话。
std::锁紧保护lk(someclass->cv\U m);
someclass->pause\u test\u threads=true;
}
}
无效取消暂停测试线程(SomeClass*SomeClass)
{
if(someclass->暂停测试线程)
{
{
//即使我们使用原子,互斥也必须在
//修改。参见条件变量的文档
//notify_all/wait。实际操作不需要保留互斥
//通知电话。
std::锁紧保护lk(someclass->cv\U m);
someclass->pause\u test\u threads=false;
}
someclass->cv.notify_all();//允许发送/接收线程运行。
void do_pause_test_threads(SomeClass *someclass)
{
if (!someclass->pause_test_threads)
{
/// your pause_test_threads might be changed here by other thread
/// so you have to acquire mutex before checking and changing
/// or use atomic methods - compare_exchange_weak/strong,
/// but not all together
std::lock_guard<std::mutex> lk(someclass->cv_m);
someclass->pause_test_threads = true;
}
}