Boost::thread库的使用(转)
原文转自 http://blog.csdn.net/lee353086/article/details/4673790
本文主要由线程启动、Interruption机制、线程同步、等待线程退出、Thread Group几个部份组成。
1、线程启动。线程可以从以下四种方式启动:
(1) 用struct结构的operator成员函数启动
struct callable { void operator()() { 这里略去若干行代码 } }; 这里略去若干行代码 Callable x; Boost::thread t(x);
(2) 以非成员函数形式启动线程
void func(int nP) { 这里略去若干行代码 } 这里略去若干行代码 Boost::thread t(func,123);
(3) 以成员函数形式启动线程
#include <boost/bind.hpp> class testBind { public: void testFunc(int i) { cout << ”i = ” << i << endl; } }; testBind tb; boost::thread t(boost::bind(&testBind::testFunc, &tb, 100));
2、Interruption机制
可以通过thread对象的interrupt函数,通知线程,需要interrupt。线程运行到interruption point就可以退出。Interruption机制举例:
#include "stdafx.h" #include <iostream> #include <boost/thread.hpp> using namespace std; void f() { for (int i = 1; i < 0x0fffffff; i++) { if (i % 0xffffff == 0) { cout << "i=" << ((i & 0x0f000000) >> 24) << endl; cout << "boost::this_thread::interruption_requested()=" << boost::this_thread::interruption_requested() << endl; if (((i & 0x0f000000) >> 24) == 5) { boost::this_thread::interruption_point(); } } } } int _tmain(int argc, _TCHAR* argv[]) { boost::thread t(f); t.interrupt(); t.join(); //等待线程结束 return 0; }
t.interrupt();告诉t线程,现在需要interrupt。boost::this_thread::interruption_requested()可以得到当前线程是否有一个interrupt请求。若有interrupt请求,线程在运行至interruption点时会结束。
boost::this_thread::interruption_point();就是一个interruption point。Interruption point有多种形式,较常用的有boost::this_thread::sleep(boost::posix_time::seconds(5));当没有interrupt请求时,这条语句会让当前线程sleep五秒,若有interrupt requirement线程结束。
如何使线程在运行到interruption point的时候,不会结束,可以参考下面的例子:
#include "stdafx.h" #include <iostream> #include <boost/thread.hpp> using namespace std; void f() { for (int i = 1; i < 0x0fffffff; i++) { if (i % 0xffffff == 0) { cout << "i=" << ((i & 0x0f000000) >> 24) << endl; cout << "boost::this_thread::interruption_requested()" << boost::this_thread::interruption_requested() << endl; if (((i & 0x0f000000) >> 24) == 5) { boost::this_thread::disable_interruption di; { boost::this_thread::interruption_point(); } } } } } int _tmain(int argc, _TCHAR* argv[]) { boost::thread t(f); t.interrupt(); t.join(); //等待线程结束 return 0; }
注意boost::this_thread::disable_interruption这条语句的使用,它可以使大括号内的interruption point不会中断当前线程。
3、线程同步
Boost提供了多种lock导致上手需要较长时间,还是看下面线程同步的例子比较简单,相信在多数应用中足够:
直接使用boost::mutex的例子
static boost::mutex g_m; 这里略去若干行代码 g_m.lock(); 需要锁定的代码 g_m.unlock(); 这里略去若干行代码 if (g_m.try_lock()) { 需要锁定的代码 } 这里略去若干行代码
使用lock guard的例子
#include <iostream> #include <string> #include <boost/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/locks.hpp> using namespace std; static boost::mutex g_m; void f(string strName) { for (int i = 1; i < 0x0fffffff; i++) { if (i % 0xffffff == 0) { boost::lock_guard<boost::mutex> lock(g_m); cout << "Name=" << strName << " i=" << ((i & 0x0f000000) >> 24) << endl; } } } int _tmain(int argc, _TCHAR* argv[]) { boost::thread t(f, string("inuyasha")); boost::thread t2(f, string("kagula")); boost::thread t3(f, string("kikyou")); { boost::lock_guard<boost::mutex> lock(g_m); cout << "thread id=" << t.get_id() << endl; } t.join(); t2.join(); t3.join(); return 0; }
使用unique lock的例子
#include <iostream> #include <string> #include <boost/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/locks.hpp> using namespace std; static boost::mutex g_m; void f(string strName) { cout << "Thread name is " << strName << "-----------------begin" << endl; for (int i = 1; i < 0x0fffffff; i++) { if (i % 0xffffff == 0) { boost::unique_lock<boost::mutex> lock(g_m); cout << "Name=" << strName << " i=" << ((i & 0x0f000000) >> 24) << endl; lock.unlock(); } } cout << "Thread name is " << strName << "-----------------end" << endl; } int _tmain(int argc, _TCHAR* argv[]) { boost::thread t(f, string("inuyasha")); boost::thread t2(f, string("kagula")); boost::thread t3(f, string("kikyou")); t.join(); t2.join(); t3.join(); return 0; }
同Lock_guard相比
[1]Unique lock中有owns lock成员函数,可判断,当前有没有被lock。
[2]在构造Unique Lock时可以指定boost::defer_lock_t参数推迟锁定,直到Unique Lock实例调用Lock。或采用下面的编码方式使用:
boost::unique_lock<boost::mutex> lock(mut,boost::defer_lock);
boost::unique_lock<boost::mutex> lock2(mut2,boost::defer_lock);
boost::lock(lock,lock2);
[3]它可以和Conditoin_variable配合使用。
[4]提供了try lock功能。
如果线程之间执行顺序上有依赖关系,直接到boost官网中参考条件变量(Condition variables)的使用。官网关于Conditon Variables的说明还是容易看懂的。
注意,使用一个不恰当的同步可能消耗掉1/2以上的cpu运算能力。
Thread Group
线程组使用示例,其中f函数在上面的例子已经定义
int _tmain(int argc, _TCHAR* argv[]) { boost::thread_group tg; tg.add_thread(new boost::thread(f,string("inuyasha"))); tg.add_thread(new boost::thread(f,string("kagula"))); tg.add_thread(new boost::thread(f,string("kikyou"))); tg.join_all(); return 0; }