就像之前我们提过的一样,很多线程需要互斥量进行相互锁定,因为很多关键数据和操作并不是线程安全,多线程处理很有可能会出很大的问题。但是互斥量又会带来一个问题,我就举个例子来说明:
比如说,现在有一组数据,可以对它进行读写操作。但是一般情况读写要分开操作,因为这样才可以让后续处理更好的执行。很明显的道理,这里读写不能同时进行,要设立互斥量。多线程同时写入也是不允许的,所以要设立互斥量。但是多线程读却是可以的。。。。。。。。。。。。。。。。这个很关键。后续的程序需要读取内容进行处理,但是读本身不改变数据,是可以多线程同时读取的。所以这个时候就显得特别蛋疼了,你说读的时候设不设立互斥量?如果设立互斥量的话,那么多个线程读是不可能的,但是如果不设立互斥量的话,就有可能在读的时候再写入。这尼玛真的是hold不住,有时候真的很想知道为毛会有这么多要求,客户真的是挑啊。
好了,言归正传。如果大家以后遇到一些步骤,有些步骤可以共存或者重复,但是和另外一些不准是不能共存的,大家一定要想到共享互斥量。
好了,大家看看我的代码,代码里面我来和大家详细说说。
// blog_shared_mutex.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#define BOOST_HAS_WINTHREADS
#define BOOST_THREAD_BUILD_DLL
#define BOOST_DATE_TIME_SOURCE
#define BOOST_THREAD_NO_LIB
//#define BOOST_THREAD_USE_LIB
#include
extern "C" void tss_cleanup_implemented(void){}
#include
#include
#include
#include
#include
#include
#include
#include
boost::mutex io_mu;
class rw_data
{
private:
int m_x;
boost::shared_mutex rw_mu;//大家注意这里的shared_mutex,他是本节 的重点
public:
rw_data():m_x(0){}
void write()
{
boost::unique_lock ul(rw_mu);//这里的unique_lock它能够锁住共享变量。如果有其他线程再次调用unique_lock或者shared_lock都会被阻塞。这里就限定了写的操作只能是由单线程去决定。
++m_x;
}
void read(int *new_data)
{
boost::shared_lock sl(rw_mu);//这里的shared_lock它也能够锁住共享变量。如果其他线程继续调用shared_lock线程不会被阻塞,会继续进行,但是如果有线程调用unique_lock企图锁住变量,就会被阻塞。
*new_data=m_x;
}
};
void writer(rw_data &d)
{
for(int i=0;i<20;++i)
{
boost::this_thread::sleep(boost::posix_time::millisec(10));//采用了一点点定时相关的程序,是希望程序出来的更加明显。这里是使用延时10ms,this_thread返回的是调用的本线程,sleep是本线程进入睡眠。
d.write();
}
}
void reader(rw_data &d)
{
int x;
for(int i=0;i<10;++i)
{
boost::this_thread::sleep(boost::posix_time::millisec(5));
d.read(&x);
boost::mutex::scoped_lock lock(io_mu);
std::cout<<"reader "<<x<<std::endl;
}
}
int main()
{
rw_data d;
boost::thread_group pool;//这里采用的是线程组。线程组用来管理一些列具有相同特性的现场。然后对这些线程进行同样的处理。
pool.create_thread(boost::bind(reader,boost::ref(d)));
pool.create_thread(boost::bind(reader,boost::ref(d)));
pool.create_thread(boost::bind(reader,boost::ref(d)));
pool.create_thread(boost::bind(reader,boost::ref(d)));
pool.create_thread(boost::bind(writer,boost::ref(d)));
pool.create_thread(boost::bind(writer,boost::ref(d)));
pool.join_all();//等待所有线程结束
return 0;
}
程序结果: