Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将std::condition_变量与原子<;布尔>;_C++_Multithreading_C++11 - Fatal编程技术网

C++ 将std::condition_变量与原子<;布尔>;

C++ 将std::condition_变量与原子<;布尔>;,c++,multithreading,c++11,C++,Multithreading,C++11,关于如何处理原子,以及如何处理std::condition_变量,有几个问题。但我的问题是,我下面的用法是否正确 三个线程,一个ctrl线程在取消暂停另外两个线程之前执行准备工作。ctrl线程还能够在工作线程(发送方/接收方)处于紧密的发送/接收循环时暂停它们。 使用原子的想法是,如果没有设置暂停的布尔值,则使紧循环更快 class SomeClass { public: //...

关于如何处理原子,以及如何处理std::condition_变量,有几个问题。但我的问题是,我下面的用法是否正确

三个线程,一个ctrl线程在取消暂停另外两个线程之前执行准备工作。ctrl线程还能够在工作线程(发送方/接收方)处于紧密的发送/接收循环时暂停它们。 使用原子的想法是,如果没有设置暂停的布尔值,则使紧循环更快

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