Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.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++ 同步的条件变量与原子类型_C++_Multithreading_C++11_Concurrency_Atomic - Fatal编程技术网

C++ 同步的条件变量与原子类型

C++ 同步的条件变量与原子类型,c++,multithreading,c++11,concurrency,atomic,C++,Multithreading,C++11,Concurrency,Atomic,假设我使用条件变量同步了生产者线程和消费者线程 // Approach 1 - Using condition variable mutex mmutex; condition_variable mcond; queue<string> mqueue; void producer(){ while (true) { unique_lock<mutex> lck(mmutex); mqueue.push_back("Hello Hi

假设我使用条件变量同步了生产者线程和消费者线程

// Approach 1 - Using condition variable
mutex mmutex;
condition_variable mcond;
queue<string> mqueue;

void producer(){
    while (true) {
        unique_lock<mutex> lck(mmutex);
        mqueue.push_back("Hello Hi");
        mcond.notify_one();
    }
}

void consumer{
    while (true){
        unique_lock<mutex> lck(mmutex); // locks mmutex
        mcond.wait(); // releases mmutex;
        string s = mqueue.front(); // locks mmutex again
        mqueue.pop();
        mmutex.unlock();
    }
}
//方法1-使用条件变量
互斥体mmutex;
条件变量mcond;
队列mqueue;
无效生产者(){
while(true){
唯一锁定lck(mmutex);
mqueue.push_back(“你好,你好”);
通知某人;
}
}
无效消费者{
while(true){
唯一的锁lck(mmutex);//锁mmutex
mcond.wait();//释放mmutex;
字符串s=mqueue.front();//再次锁定mmutex
mqueue.pop();
mmutex.unlock();
}
}
对于使用简单原子类型的同步,上面的代码如何比较,如下所示-

// Approach 2 - using atomics
atomic_bool condition = false;
condition_variable mcond;
queue<string> mqueue;

void producer(){
    unique_lock<mutex> lck(mmutex);
    mqueue.push_back("Hello Hi");
    condition = true;
}

void consumer{
    while (1) {
        if (condition == true) {
            condition = false;
            unique_lock<mutex> lck(mmutex);
            mqueue.front();
            mqueue.pop();
            lck.unlock();
        }
    }
}
//方法2-使用原子
原子布尔条件=假;
条件变量mcond;
队列mqueue;
无效生产者(){
唯一锁定lck(mmutex);
mqueue.push_back(“你好,你好”);
条件=真;
}
无效消费者{
而(1){
如果(条件==真){
条件=假;
唯一锁定lck(mmutex);
mqueue.front();
mqueue.pop();
lck.unlock();
}
}
}

由于存在条件变量,我假设它们是在类似情况下实现同步的首选方法。如果确实如此,为什么条件变量是基于简单原子布尔(或者如果需要两个以上状态,则为原子int)的同步的更好的替代方案?如果没有,那么在这种情况下实现同步的最佳方法是什么?

不同之处在于,条件变量不会在另一个线程等待时消耗CPU周期。如果使用原子变量进行同步,则必须在循环中不断检查其值。

如果使用多核处理器,使用条件变量是否仍能比其他方法提高性能?@FirstJens-是的,这就是它们的设计目的。如果你有一个线程在一个紧循环中等待一个原子变量得到一个特定的值,那么不管你有多少个处理器,你都在消耗CPU周期。在特殊情况下,忙等待可能比使用条件变量更快。如果您的整个应用程序在2个CPU上运行2个线程(具体地说,您为使用者线程授予了一个专用CPU),而没有与其他应用程序发生争用,那么繁忙的等待可能会加快线程之间的数据传输。条件变量在两个线程中都做额外的工作,例如切换到内核或从内核切换,这并不便宜。在多任务环境中,为繁忙的等待而浪费CPU通常是不可接受的。这也是我们有收益的原因<代码>而(!ready){std::this_thread::yield();}
等待
需要用锁调用。您需要处理虚假唤醒。@T.C.您确定需要使用锁定消费者调用等待吗?我是由Bjarne Stroustrup从C++中复制代码的。你知道,如果生产者比消费者快,那么你的解决方案都不起作用吗?条件变量解决方案也不会处理虚假唤醒。@谢谢。我在读关于假尾波的书。是的,我知道如果生产者的速度快于消费者,我的代码将失败