并发,std::condition_variable_any

梦想游戏人
目录:
现代C++

等待特定条件的唤醒,条件变量通常和互斥锁 搭配使用。mutex 一般对资源是抢占式的,如果想等待某个线程先执行 ,然后再执行 可用条件变量

等待变量代码情况还必须使用 mutex。                  对的调用的线程必须锁定 mutex,然后再调用情况等待变量的函数。 当调用函数返回时,mutex 将阻塞。 当线程等待条件变为 true 时,mutex 不锁定。 不可预知的结果,因而不等待环境变量的每个线程都必须使用同一 mutex 对象。

类型 condition_variable_any 对象可用于任何类型 mutex。 mutex 使用的类型不必须提供 try_lock 方法。 类型 condition_variable 对象只能与 unique_lock<mutex>类型 mutex。 此类型对象比类型 condition_variable_any<unique_lock<mutex>>对象可能快。

要等到事件,请先锁定 mutex,然后调用一在条件变量的 wait 方法。 直到另一个线程中调用 wait 块终止条件变量。

“虚拟”唤醒 发生情况,当等待变量的线程已取消,而没有相应的通知。 若要识别此”虚拟”唤醒,则条件变为 true 的代码应显式检查条件,如果代码从等待功能时返回。 使用循环,这通常执行;可以使用 wait(unique_lock<mutex>& lock, Predicate pred) 为您执行此循环。

.
//读线程等待写线程完毕后 唤醒

std::mutex _mutex;//全局互斥锁

std::condition_variable_any condition;//全局条件变量

int x = 1;//全局资源

void func_1()//write thread
{
	Sleep(100);

        { 
	    lock_guard<std::mutex> lock(_mutex);
	    x += 1;
        } 
	condition.notify_one(); //唤醒,等待写入而挂起的读线程

}

void func_2()//read thread
{
	unique_lock<std::mutex>lock(_mutex) ;

	condition.wait(_mutex);//挂起该线程,等待修改完数据的线程唤醒,
	cout << x << endl;

}


int main(int argc, char *argv[])
{

	auto t = std::thread(func_1);//写线程

	t.detach();

	auto t1 = std::thread(func_2);//读线程

	t1.detach();

	Sleep(300);

	cout << x << endl;
	cout << "main thread" << endl;



	system("pause");
	return 0;
}



condition_variable 只能和std::mutex 搭配使用

condition_variable_any 则更广的使用范围


	std::thread t([&]
	{
		while (true)
		{
			while (1)
			{
				mm.lock();

				con.wait(mm, [&](){return !_queue.empty(); });//被通知后,第二个参数返回值是true的时候 
                //  才会解除阻塞
				cout << "getMsg" << endl;
				mm.unlock();

			}
			


			while (_queue.empty())
			{
				mm.lock();
				con.wait_for(mm,std::chrono::milliseconds(100));//固定时间的等待

				cout << "getMsg" << endl;
				mm.unlock();

			}


	        while (_queue.empty())
			{
				mm.lock();
				con.wait_for(mm));//一直等待直到 被通知

				cout << "getMsg" << endl;
				mm.unlock();

			}
		}

	});

	t.detach();

MSDN 参考,https://msdn.microsoft.com/zh-cn/library/hh874761(v=vs.120).aspx

Scroll Up