boost 多线程编程(二)

一.互斥量的介绍

1. 互斥量主要是用于线程间的同步,在多线程中主要是防止多个线程同时操作共享资源。

2.互斥的基本原则是,一旦某一个线程拥有互斥变量的所有权,操作共享的资源时,那么其他的线程就处于等待中,等待这个互斥量的所有权,一旦拥有所有权的线程释放互斥变量时,其他的线程才能取得互斥变量的所有权。

3.互斥量分为两种:独占式和共享式,互斥变量mutex的对象类大致如下:

    (1).mutex,独占式互斥量,最简单的,而且是最常用的一种互斥变量。

    (2).timed_mutex ,独占式互斥量,并提供超时锁定功能。

    (3).recursive_mutex: 递归式互斥量,可以多次锁定,相应地也要多次解锁。

    (4).recursive_timed_mutex: 它也是递归式互斥量,提供超时锁定功能。

    (5).shared_mutex: multiple-reader/single-writer 型的共享互斥量(又称读写锁)。

二.下面来看个简单的例子:

#include <boost/thread.hpp> 
#include <iostream> 

using namespace std;

boost::mutex mutex;   //定义一个锁
void wait(int seconds) 
{ 
  boost::this_thread::sleep(boost::posix_time::seconds(seconds)); 
} 
void thread() 
{ 
  for (int i = 0; i < 5; ++i) 
  { 
    wait(2); 
    mutex.lock();  //上锁
    std::cout << "Thread " << boost::this_thread::get_id() << ": " << i << std::endl; //多线程非安全的
    mutex.unlock();   //释放锁
  } 
} 
int main() 
{ 
  boost::thread t1(thread); 
  boost::thread t2(thread); 
  t1.join(); 
  t2.join(); 
} 

由于cout打印是线程非安全的,所以cout 打印在多线程中存在着资源的竞争性,多线程使用时需要加锁。另外,上锁操作完资源后,需要记得释放锁。程序运行的最后结果如下:


三.lock模板类使用

lock模板类也分为独占式的 和共享式的。lock模板类与mutex对象结合使用,在lock构造函数中调用互斥体mutex的lock方法,mutex对象 被锁住,一旦离开作用域,会自动调用lock的析构函数,释放锁。

(1).boost::unique_lock<T>,其中T可以mutex中的任意一种。(独占式),如:

     boost::unique_lock<boost::mutex>,构造与析构时则分别自动调用lock和unlock方法,不需要手动的释放锁。

(2).boost::shared_lock<T>,其中的T只能是shared_mutex类。(共享锁)

四.下面以读写锁来举个例子

#include <boost/thread/locks.hpp>
#include <boost/thread.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <iostream>
#include <functional>
#include <boost/function.hpp>   
#include <boost/bind.hpp>
using namespace std;


boost::shared_mutex mutex_;//共享锁
boost::mutex g_io_mutex;

void wait(int seconds) 
{ 
  boost::this_thread::sleep(boost::posix_time::seconds(seconds)); 
}

class Counter 
{
public:
  Counter() : value_(0) {}
 
  size_t Get() const 
  {
    boost::shared_lock<boost::shared_mutex> lock(mutex_);  //shared_lock 和share_mutex 配合使用
    return value_;
  }

  void Put()   //同一时间 只能有一个线程来访问
  {
    boost::unique_lock<boost::shared_mutex> lock(mutex_); //使用lock模板类
    value_++;
  }

private: 
  size_t value_;
};

void threadFunc(Counter& counter) 
{
  for (int i = 0; i < 3; ++i) 
  {
    counter.Put(); //写入数据,锁住mutex
    size_t value = counter.Get(); //多个线程可以同时读取数据
    boost::lock_guard<boost::mutex> lock(g_io_mutex);  //锁定 cout 打印输出,cout 是非线程安全的
    std::cout << boost::this_thread::get_id() << ' ' << value << std::endl;
  }
}

int main() 
{
	
  Counter counter;

  boost::thread_group threads; //boost threads的线程组
  for(int i =0;i< 3;i++)
  {
	  threads.create_thread(boost::bind(threadFunc, boost::ref(counter)));//ref传入引用
  }
  
  threads.join_all();
  return 0;
}



上例子中使用共享锁对象boost::shared_mutex,在写入数据时,mutex锁住 只能有一个线程可以写入数据,读取数据的时候,多个线程可以同时读取数据。在读取的时候,会阻塞所有企图写入数据的线程,知道所有的读取数据的线程访问结束,析构lock对象,释放锁时,才能获取到mutex的对象所有权。同理,在写入数据的时候,会阻塞任意一个企图写和企图读数据的线程。

程序的运行结果如下:



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值