c++11的condition_variable的wait的理解

unconditional (1)
void wait (unique_lock<mutex>& lck);
predicate (2)
template <class Predicate>  void wait (unique_lock<mutex>& 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<std::mutex> 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<std::mutex> 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++11中引入了condition_variable类,用于实现线程间的同步和通信。condition_variable类提供了wait()和notify()等函数,可以实现类似pthread_cond_wait()和pthread_cond_signal()的功能。 要实现类似pthread_cond_timedwait()的功能,可以结合condition_variable和unique_lock来实现。下面是一个简单的示例代码: ```cpp #include <iostream> #include <thread> #include <mutex> #include <condition_variable> #include <chrono> std::mutex mtx; std::condition_variable cv; bool ready = false; void worker_thread() { std::this_thread::sleep_for(std::chrono::seconds(2)); std::unique_lock<std::mutex> lock(mtx); ready = true; cv.notify_one(); } int main() { std::cout << "Main thread starts." << std::endl; std::thread worker(worker_thread); std::unique_lock<std::mutex> lock(mtx); if (cv.wait_for(lock, std::chrono::seconds(3), []{ return ready; })) { std::cout << "Worker thread signaled." << std::endl; } else { std::cout << "Timeout occurred." << std::endl; } worker.join(); std::cout << "Main thread ends." << std::endl; return 0; } ``` 在上面的示例中,worker_thread函数是工作线程,它会在2秒后将ready标志设置为true,并通过cv.notify_one()通知等待的线程。 在主线程中,我们使用cv.wait_for()函数等待条件变量的通知,等待时间为3秒。如果在等待时间内收到通知,则输出"Worker thread signaled.";如果超过等待时间仍未收到通知,则输出"Timeout occurred."。 注意,在使用condition_variable时,需要结合unique_lock来进行互斥锁的管理,以确保线程安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值