c++11的condition_variable的wait的理解

unconditional (1)
void wait (unique_lock& lck);
predicate (2)
template   void wait (unique_lock& lck, Predicate pred);

wait() 工作机制的总结

1.condition_variable的wait首先会block当前线程,然后进行互斥量的unlock

(因此,一般上使用wait前,会RAII构造互斥量的lock)

2.  注意,block和unlock必须是个原子动作。

3.最后conditon_variable会把当前线程添加如检测等待队列

4.此时当前线程等待...

5.其他线程执行了这个condition_variable的notify

6.先互斥量的lock,然后unblock。(即跳出wait动作)

7.最后unlock(运行期结束或主动调用unlock)

补充:如果wait函数还传入了第二个参数pred,pred参数应当是个bool型的可调用对象

此时调用wait,会先判断第二个参数的返回值,如果返回false,就会执行wait,否则直接返回;

当被唤醒后再次判断第二个参数的返回值,如果返回false,会再次进入阻塞,否则直接返回;

如此反复。

例子:10消费者,1个生产者

///以下是10个消费者线程,一个生产者线程
std::mutex mtx2;
std::condition_variable _cond2;
int cargo_2 = 0;

struct is_judge2 {
	bool operator()() {
		return cargo_2;
	}
};

struct is_judge2_ext {
	int m_i = 0;
	is_judge2_ext(int iv) :m_i(iv) {};
	bool operator()() {
		//std::cout << "cago " << m_i << "  " << cargo_2 << std::endl;
		return cargo_2 == m_i;
	}
};

void consume3(int iIdx)
{
	std::unique_lock lck(mtx2);
	if (0) {
		_cond2.wait(lck, is_judge2());
	}
	else {
		std::cout << "wait " << iIdx << std::endl;
		_cond2.wait(lck, is_judge2_ext(iIdx));
	}
	std::cout << "exit " << iIdx << std::endl;

	cargo_2 = 0;
}

void test_cond3()		//接口,同时也作为生产者
{
	int CNT = 10;
	std::thread _thd[10];
	for (int i = 0; i < CNT; i++) {
		_thd[i] = std::thread(consume3, i + 1);
	}

	for (int i = 0; i < CNT; i++) {
		int times = 0;
		while (cargo_2) {
			std::this_thread::yield();
			times++;
		}

		{
			std::unique_lock lck(mtx2);
			cargo_2 = 10 - i;
		}

		std::cout << "\nSC   " << cargo_2 << "  " << times << std::endl;
		//条件变量通知无须持有锁的!!!
		_cond2.notify_all();
	}

	for (auto& _iter: _thd) {
		_iter.join();
	}

	int k = 0;
}

你可能感兴趣的:(c++,开发语言)