boost::thread库 并发编程

所在文件和命名空间:

#include <boost/thread.hpp>
using namespace boost;

1. 时间功能

多线程编程经常要用到超时处理,需要表示时间的概念,thread库直接利用date_tiem库提供对时间的支持。

this_thread::sleep(posix_time::seconds(2));  //当前线程睡眠两秒
//this_thread是thread的子命名空间

2. boost::mutex 互斥量

互斥量:一种线程同步手段,可以在多线程编程中防止多个线程同时操作共享资源(或称临界区)。

//最简单最常用的互斥量类型:独占式互斥量
typedef boost::mutex mutex_t;

//基本用法
mutex_t mu;
mu.lock();
//do something
mu.unlock();

3. RAII型的lock_guard类

直接使用mutex的lock()函数来锁定互斥量不够方便,且在发生异常退出作用域等情况下很可能忘记解锁。
故,thread库提供了RAII型lock_guard类,辅助:在构造时锁定互斥量,析构时自动解锁。
mutex类使用内部类型定义了两种lock_guard对象:
1. scoped_lock
2. scoped_try_lock

mutex mu;
mutex::scoped_lock lock(mu);
//do something

4. 互斥量实例

使用mutex实现一个原子操作的计数器basic_atom,多线程安全的计数:

template<typename T>
class basic_atom:boost::noncopyable
{
public:
    //构造函数
    basic_atom(T x=T()):n(x){}

    //前置式递增操作
    T operator++(){
        mutex::scoped_lock lock(mu);
        return ++n;
    }

    T operator()(){
        return n;
    }

private:
    T n;
    typedef mutex mutex_t;
    mutex_t mu;

};

typedef basic_atom<int> atom_int;

5. 线程

thread类是thread库的核心类,从类摘要中就可以看出thread的操作方式:

这里写图片描述

  1. 当创建一个thread对象后,线程就立刻开始执行。
  2. join()和timed_join()方法等待线程结束。
    1. join()一直阻塞等待,直到线程结束。
    2. timed_join()阻塞等待线程结束,或阻塞等待一定的时间段,然后不管线程是否结束都返回。
  3. detach()与线程执行体分离,线程执行体不受影响的继续执行直到运行结束。
  4. 可以使用bind()和function库。
  5. thread类的3个静态成员函数:
    1. yield() 指示当前线程放弃时间片,允许其他的线程运行。
    2. sleep() 让线程睡眠等待一小段时间。
    3. hardware_concurrency() 获得硬件系统可并行的线程数量,即CPU数量。
  6. thread::this_thread 子命名空间:
    1. get_id() 获得线程ID
    2. yield() 放弃时间片
    3. sleep() 睡眠等待
    4. at_thread_exit(func)函数,允许“登记”一个线程在结束的时候执行可调用物func,无论线程是否被中断。
  7. interrupt() 中断线程,允许正在执行的线程被中断,被中断的线程会抛出一个thread_interrupted异常。

使用实例:


//#define BOOST_DATE_TIME_SOURCE
//#define BOOST_THREAD_NO_LIB
#include <boost/thread.hpp>
#include <boost/ref.hpp>
#include < boost/typeof/typeof.hpp >

#include <boost/bind.hpp>
#include <boost/function.hpp>

using namespace boost;

#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;


//typedef mutex mutex_t;
//mutex_t io_mu;

template<typename T>
class basic_atom:boost::noncopyable
{
public:
    //构造函数
    basic_atom(T x=T()):n(x){}

    //前置式递增操作
    T operator++(){
        mutex::scoped_lock lock(mu);
        return ++n;
    }

    T operator()(){
        return n;
    }

private:
    T n;
    typedef mutex mutex_t;
    mutex_t mu;

};

typedef basic_atom<int> atom_int;

mutex io_mu;

void end_msg()
{
    cout<<"this is the end of the thread"<<endl;
}

void printing(atom_int &x,const string &str)
{
    for(int i=0;i<5;i++){
        mutex::scoped_lock lock(io_mu);
        cout<<str<<++x<<endl;
    }
    this_thread::at_thread_exit(bind(end_msg));

}

void fun()
{
    //cout<<this_thread::get_id()<<endl;
    cout<<"liudong"<<endl;
    cout<<this_thread::get_id()<<endl;
}

void interrupt_func(atom_int &x,const string &str)
{
    try{
        for(int i=0;i<5;i++){
            this_thread::sleep(posix_time::seconds(1));
            mutex::scoped_lock lock(io_mu);
            cout<<str<<++x<<endl;
            this_thread::interruption_point();  //指定线程中断点。
        }
    }
    catch(thread_interrupted&){
        cout<<"thread: "<<this_thread::get_id()<<"interrupted"<<endl;
    }

}


int main()
{
    /*
    cout<<"cpus is "<<thread::hardware_concurrency()<<endl;
    fun();
    thread t1(fun);
    thread t2(fun);

    cout<<this_thread::get_id()<<endl;
    //this_thread::sleep(posix_time::seconds(2));
    t1.join();
    t2.join();
    cout<<"all joined"<<endl;
    */

    atom_int x;
    //thread t1=thread(printing,ref(x),"hello");
    thread t1(printing,ref(x),"thread1 ");

    function<void()> f=boost::bind(printing,ref(x),"thread2 ");
    //thread t2=thread(printing,ref(x),"boost");
    //f=boost::bind(interrupt_func,ref(x),"thread2");
    thread t2=thread(f);

    //t1.join();
    /*
    t1.detach();
    t2.interrupt();
    t2.join();
    */

    /*
    thread_group tg;
    tg.add_thread(&t1);
    tg.add_thread(&t2);
    tg.join_all();
    tg.~thread_group();
    */
    t1.join();
    t2.join();

    cout<<"the end of main program"<<endl;

    return 0;

}

6. 线程组(线程池)thread_group类

thread类提供thread_group类用于管理一组线程,就像是一个线程池,它内部使用std::list<thread*>来容纳创建的thread对象。
类摘要如下:

这里写图片描述

使用thread_group,可以为程序建立一个类似于全局线程池对象,统一管理程序中使用的thread。

7. 条件变量

条件变量是thread库提供的另一种用于等待的同步机制,可以实现线程间的通信,它必须和互斥量配合使用,等待另一个线程中某个事件的发送(满足某个条件),然后线程才能继续执行。
thread库提供两种条件变量对象:
1. condition_variable
2. condition_variable_any (常用,能够适应更广泛的互斥量类型)

这里写图片描述

使用条件变量实现的 生产者-消费者模式的后进先出型(std::stack)缓冲区
见我的另一篇博客:
http://blog.csdn.net/yvhqbat/article/details/51922153

8. 线程本地存储

线程本地存储(thread local storage)或者称 线程专有存储(thread specific storage, 简称 tss):使变量用起来就像每个线程独立拥有,可以简化多线程应用,提高性能。
thread库 thread_specific_ptr 实现线程本地存储。

9. at_thread_exit()

线程结束时执行操作。
at_thread_exit(func)函数,允许“登记”一个线程在结束的时候执行可调用物func,无论线程是否被中断。

at_thread_exit(bind(end_msg,"end"));  
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值