c++11多线程编程之condition_variable

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ypy9323/article/details/81585921

一、condition_variable

     多线程编程中,常会涉及生产者线程与消费者线程同步问题。c++新标准库(boost)中condition_variable比使用mutex更精确的控制线程执行。简单说就是其中一个线程会及时通知其它线程,已经把数据处理好了。等待中的线程得到“通知”被唤醒来处理数据。

 二、示例代码

        通过以下代码来说明其工作方式。

#include <QtCore/QCoreApplication>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>

const int count = 110;
std::mutex g_mutex;
std::condition_variable g_wait_condition;
int value = 0;

bool volatile b_yield = false;

void wait_thread(int n) 
{
	std::cout << "wait thread id: " << std::this_thread::get_id() << std::endl;
	for (int i = 0; i < n; ++i) {
		std::unique_lock<std::mutex> lock(g_mutex);
		g_wait_condition.wait(lock, []() {return b_yield; });
		std::cout << "count: " << i+1 << 
              " custom thread print: value= " << value << std::endl;
		b_yield = false;
	}
}

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

	std::thread sub_thread(wait_thread, count);
	std::cout << "main thread id: " << std::this_thread::get_id() << std::endl;

	for (int i = 1; i <= count; i++) {
		while (b_yield)
			std::this_thread::yield();

		std::unique_lock<std::mutex> lock(g_mutex);  //[1]
		value = i;
		if (value % 2 == 0) {
			b_yield = true;
			g_wait_condition.notify_one();
		} else {
			std::cout << "main print: value= " << value << std::endl;
		}
	}

	sub_thread.join();

	return a.exec();
}

1>先来明确定义的几个变量用意:

     value:P、C两线程要读/写的临界资源。

     g_mutex: P、C两线程同步互斥量。通过加锁mutex来保证只有一个线程可以访问value。

     g_wait_condition: 

    b_yield: bool 值,等待条件

2>P线程(main() 所在,它负责累加value,当value为2的倍数时唤醒C线程)

    P线程首先要知道被唤醒C线程是否已经处理完自己最近一次“生产”的数据([0]所示),否则应该放弃执行权。在”生产“下一个数据时首先进行对互斥量上锁std::unique_lock<std::mutex> lock(g_mutex);([1]所示)上锁成功便可以写临界资源value。假如这个数是2的倍数。将b_yileld置为true。同时唤醒一个等待(阻塞)中的线程。

3> C 线程(wait_thread(int n)所在,主要逻辑是输出value为2的倍数时的值)

   在访问value时也要进行加锁处理,假如加锁失败那是因为P线程在写value,它会被阻塞。

   g_wait_condition.wait(lock, []() {return b_yield; }); //[3]  wait() 函数要检查等待条件是否满足,如果满足则返回,也就是说函数    继续执行,做其数据处理。假如不满足将解锁互斥量,同时使得线程阻塞。一旦有线程对同一condition_variable调用                   notify_one()该线程”得到通知“立马”苏醒“。做数据处理。

  它将b_yileld 置为false。以便消费者线程可以准备下一个数据。

【注】在多线程中使用condition_variable我们更应该做到消费者线程先执行,以便让其先进入”wait“状态。

三、程序部分运行结果截图如下:

猜你喜欢

转载自blog.csdn.net/ypy9323/article/details/81585921