boost并发编程(三)——共享互斥量

前一篇介绍的条件变量可以进行进程间通信,用来实现生产者/消费者模型。今天介绍的共享互斥量用来实现缓冲区读写模型,与生产者/消费者模型不同的地方是,消费者消费产品后,被消费的产品就不存在了,所以消费者线程也要互斥运行;而缓冲区读取线程读取数据后不删除数据,多个线程可以并行读取。这时使用条件变量也不合适了,就要使用共享互斥变量了。

共享互斥量,顾名思义,既共享,也互斥,读线程之间共享读取数据,使用shared_lock类锁定shared_mutex变量;写线程之间需要独占缓冲区,必须互斥运行,使用unique_lock类锁定shared_mutex变量。这与互斥变量mutex的使用方法不一样,mutex类内部提供了一种lock_guard类即scope_lock类,因此可以用

mutex::scope_lock lock(mu);

这样的形式来锁定互斥量,而share_mutex类没有提供这种内部定义的lock_guard类,所以需要直接使用lock_guard对象,语法如下代码:

shared_mutex rw_mu;

unique_lock<shared_mutex> ul(rw_mu);
shared_lock<shared_mutex> sl(rw_mu);

下面是《指南》上的例子:

private:
		int m_x;
		shared_mutex rw_mu;

public:
		rw_data():m_x(0){}

		void write()
		{
			unique_lock<shared_mutex> ul(rw_mu);
			++m_x;
		}

		void read(int& x)
		{
			shared_lock<shared_mutex> sl(rw_mu);
			x = m_x;
		}
};

void writer(rw_data& d)
{
	for(int i = 0; i < 20; ++i)
	{
		this_thread::sleep(posix_time::millisec(10));
		d.write();
	}
}

void reader(rw_data& d, mutex& io_mu)
{
	int x;

	for(int i = 0; i < 10; ++i)
	{
		this_thread::sleep(posix_time::millisec(5));
		d.read(x);
		mutex::scoped_lock lock(io_mu);
		std::cout << "reader:" << x << std::endl;
	}
}

int main()
{
   rw_data d;
   thread_group pool;
   mutex io_mu;

   pool.create_thread(bind(reader,ref(d), ref(io_mu)));
   pool.create_thread(bind(reader,ref(d), ref(io_mu)));
   pool.create_thread(bind(reader,ref(d), ref(io_mu)));
   pool.create_thread(bind(reader,ref(d), ref(io_mu)));
   pool.create_thread(bind(writer,ref(d)));
   pool.create_thread(bind(writer,ref(d)));

   pool.join_all();

   return 0;
}

main函数里的thread_group类和bind适配器后面的文章再说吧,这就是共享互斥量的简单使用方法。

时间: 06-16

boost并发编程(三)——共享互斥量的相关文章

java并发编程之四、互斥

前面说了并发任务之间的分工和协作,现在说并发任务之间同样很重要,甚至更重要的一个方面,互斥.因为分工.协作和互斥这三个方面,从重要性上来讲,或许可以三分天下,但从复杂性和可探讨性来讲,互斥显然更胜一筹,对互斥的深入使用,更加体现了一个人的并发编程能力. 互斥,即同一时间只能有一个并发任务可以对数据的进行访问.大多数编程语言在这里都使用的锁机制,java自然也不例外,当然java中提供了多种互斥机制,不过是锁的不同实现. 一.Synchronized synchronized可以说是java中所最

Java并发编程三个性质:原子性、可见性、有序性

并发编程 并发程序要正确地执行,必须要保证其具备原子性.可见性以及有序性:只要有一个没有被保证,就有可能会导致程序运行不正确 线程不安全在编译.测试甚至上线使用时,并不一定能发现,因为受到当时的CPU调度顺序,线程个数.指令重排的影响,偶然触发 线程安全的定义 比如说一个类,不论通过怎样的调度执行顺序,并且调用处不用对其进行同步操作,其都能表现出正确的行为,则这个类就是线程安全的 并发编程三个概念 原子性: 一个操作或多个操作要么全部执行且执行过程不被中断,要么不执行 可见性: 多个线程修改同一

并发编程三要素:原子性,有序性,可见性

并发编程三要素 原子性:一个不可再被分割的颗粒.原子性指的是一个或多个操作要么全部执行成功要么全部执行失败. 有序性: 程序执行的顺序按照代码的先后顺序执行.(处理器可能会对指令进行重排序) 可见性: 一个县城对共享变量的修改,另一个线程能够立刻看到. 一.原子性 线程切换会带来原子性的问题 int i = 1; // 原子操作 i++; // 非原子操作,从主内存读取 i 到线程工作内存,进行 +1,再把 i 写到主内存. 虽然读取和写入都是原子操作,但合起来就不属于原子操作,我们又叫这种为"

漫谈并发编程(三):共享受限资源

解决共享资源竞争 一个不正确的访问资源示例 考虑下面的例子,其中一个任务产生偶数,而其他任务消费这些数字.这里,消费者任务的唯一工作就是检查偶数的有效性. 我们先定义一个偶数生成器的抽象父类. public abstract class IntGenerator { private volatile boolean canceled = false; public abstract int next( ); public void cancle( ) { canceled = true; } p

boost并发编程(一)——互斥锁

这个系列其实是<Boost程序库完全开发指南>的读书笔记.按照书中的方法代码没跑起来,所以转到Ubuntu下学习了.boost库在Ubuntu下的安装,直接用apt-get install命令安装就可以了,需要安装libboost-dev libboost-system libboost-thread 我们直接上代码,通过讲解代码来学习.一方面,更详细的内容请参看原书,在此不作重复:另一方面,先把代码跑起来比看了半天书连几行代码都运行不起来更能激励学习. #include <boost/

JAVA 并发编程-传统线程互斥技术(Synchronized)(三)

java线程互斥是为了保证,同一时刻最多只有一个线程执行该段代码.那么它的出现又是为了解决什么问题呢?账户存取款,在同一时间段只能让一个人进行操作. 下面来看一个简单实例(多线程带来的问题): public class TraditionalThreadSynchronized { /** * @param args */ public static void main(String[] args) { new TraditionalThreadSynchronized().init(); }

Java并发编程(三) 并发类库中的常用类

1. 同步容器类 遗留下来的同步容器类包括Vector和Hashtable,此外java.util.Collections类中还提供了以下工厂方法创建线程安全的容器对象: Collections.synchronizedList 返回支持同步操作(线程安全)的List对象: Collections.synchronizedSet 返回支持同步操作(线程全的)的Set对象: Collections.synchronizedMap 返回支持同步操作(线程安全)的Map对象: 需要注意的是,同步容器类

[Java并发编程实战] 共享对象之可见性

「 盛年不重来,一日难再晨,及时当勉励,岁月不待人.」 陶渊明 我们已经知道同步代码块和同步方法可以保证以原子的方式执行,其实,同步还有另外一个重要概念:内存可见性.换句话说,我们不仅希望防止某个线程正在使用对象状态而另一个线程同时在修改状态,而且希望确保当一个线程修改了对象的状态后,其他线程能够看到修改后的状态. 可见性 一个线程对共享变量值的修改,能够及时的被其他线程看到.可见性微妙的,这是因为可能发生错误的事情总是与直觉大相径庭.来看下面这个例子和他的执行结果: 1public class

马士兵java高并发编程三

1.使用静态内部类实现线程安全的单例模式 package com.weiyuan.test; /** * 采用内部类的形式实现单例模式 * 是同步安全的,并且实现了懒加载 * */ public class Sigleton { private Sigleton(){ } private static class Inner{ private static Sigleton s = new Sigleton(); } public static Sigleton getInstance(){ r