Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.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::条件变量_C++_C++11_Condition Variable - Fatal编程技术网

C++ 理解std::条件变量

C++ 理解std::条件变量,c++,c++11,condition-variable,C++,C++11,Condition Variable,当有多个线程等待执行时,我试图理解condition_变量的流程。据我所知,所有线程都会尝试获取唯一的锁,一个线程会获得它,然后前进到wait(),如果调用notify_all,那么最多不会有一个线程等待被允许通过。直到它释放锁并允许其他线程通过 cv是否与唯一锁通信并让所有线程同时通过?如果是这样的话,它是真的一次完成的,还是线程顺序地一个接一个地通过呢 std::condition_variable cv; std::mutex cv_m; // This mutex is used for

当有多个线程等待执行时,我试图理解condition_变量的流程。据我所知,所有线程都会尝试获取唯一的锁,一个线程会获得它,然后前进到wait(),如果调用notify_all,那么最多不会有一个线程等待被允许通过。直到它释放锁并允许其他线程通过

cv是否与唯一锁通信并让所有线程同时通过?如果是这样的话,它是真的一次完成的,还是线程顺序地一个接一个地通过呢

std::condition_variable cv;
std::mutex cv_m; // This mutex is used for three purposes:
                 // 1) to synchronize accesses to i
                 // 2) to synchronize accesses to std::cerr
                 // 3) for the condition variable cv
int i = 0;

void waits()
{
    std::unique_lock<std::mutex> lk(cv_m);
    std::cerr << "Waiting... \n";
    cv.wait(lk, []{return i == 1;});
    std::cerr << "...finished waiting. i == 1\n";
}
std::条件变量cv;
std::mutex cv_m;//此互斥用于三个目的:
//1)同步对i的访问
//2)同步对std::cerr的访问
//3)对于条件变量cv
int i=0;
void waits()
{
std::唯一锁定lk(cv_m);

std::cerr当线程必须一次调用一个
wait
时,当它们在等待时,它们不持有锁。因此,其他线程可以通过
wait
函数。

当调用(单参数版本)时,锁被解锁,线程进入等待状态,直到CV被“通知”.当线程唤醒时,锁再次锁定

当您调用时,基本上会通知等待CV的随机线程。当您调用时,等待CV的所有线程都将从等待状态中唤醒,第一个锁定该锁的线程将是继续锁定的线程。这也是随机的


注意,当我说“随机”时,线程的实际实现(从C++库到操作系统内核,甚至硬件)在您的系统上,可以通过某种方式来推断哪个线程将被唤醒并获得锁,但是从我们使用条件变量的应用程序编写者的角度来看,没有预先确定的顺序,它是随机的。

因此,第一个抓取锁的线程将经历等待,直到释放它锁。这样他们就可以按顺序通过,而不是一次全部通过。谢谢you@JoshuaWaring值得一提的是,解锁和进入等待状态(在
等待
中)需要以原子方式进行。为了完整性,大多数POSIX实现允许虚假唤醒,这意味着在极少数情况下(通常在激烈争用下),
notify_one
可以唤醒多个线程。更准确地说,POSIX示例实现允许底层函数
pthread_cond_signal
唤醒一个正在等待的线程和任何数量的即将开始等待的线程。因此,即使使用单个
notify_one
来执行特定任务,它仍然是有效的仍然需要锁定互斥锁。