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