|
|
boost::thread简要分析(1):thread |
|
|
作者:未知 来源:月光软件站 加入时间:2005-6-5 月光软件站 |
昨天在写作“大卫的Design Patterns学习笔记”过程中,编写了一个多线程Producer-Consumer的示例,其中用到了boost::thread,但在线程同步的问题上遇到了些问题,到csdn和vckbase上发帖子问了一下,也没人回答,没有办法,只好晚上回家搬出源码研究了一下,总算解决了问题,下面将自己的理解写下来,与大家分享、讨论。 注:以下讨论基于boost1.32.0。
boost::thread库跟boost::function等很多其它boost组成库不同,它只是一个跨平台封装库(简单的说,就是根据不同的宏调用不同的API),里面没有太多的GP编程技巧,因此,研究起来比较简单。
boost::thread库主要由以下部分组成: thread mutex scoped_lock condition xtime barrier 下面依次解析如下:
thread thread自然是boost::thread库的主角,但thread类的实现总体上是比较简单的,前面已经说过,thread只是一个跨平台的线程封装库,其中按照所使用的编译选项的不同,分别决定使用Windows线程API还是pthread,或者Macintosh Carbon平台的thread实现。以下只讨论Windows,即使用BOOST_HAS_WINTHREADS的情况。 thread类提供了两种构造函数: thread::thread() thread::thread(const function0<void>& threadfunc) 第一种构造函数用于调用GetCurrentThread构造一个当前线程的thread对象,第二种则通过传入一个函数或者一个functor来创建一个新的线程。第二种情况下,thread类在其构造函数中间接调用CreateThread来创建线程,并将线程句柄保存到成员变量m_thread中,并执行传入的函数,或执行functor的operator ()方法来启动工作线程。 此外,thread类有一个Windows下的程序员可能不大熟悉的成员函数join,线程(通常是主线程)可以通过调用join函数来等待另一线程(通常是工作线程)退出,join的实现也十分简单,是调用WaitForSingleObject来实现的: WaitForSingleObject(reinterpret_cast<HANDLE>(m_thread), INFINITE); 我们可以用以下三种方式启动一个新线程: 1、传递一个工作函数来构造一个工作线程 #include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> #include <iostream>
boost::mutex io_mutex;
void count() // worker function { for (int i = 0; i < 10; ++i) { boost::mutex::scoped_lock lock(io_mutex); std::cout << i << std::endl; } }
int main(int argc, char* argv[]) { boost::thread thrd1(&count); boost::thread thrd2(&count); thrd1.join(); thrd2.join();
return 0; } 2、传递一个functor对象来构造一个工作线程 #include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> #include <iostream>
boost::mutex io_mutex;
struct count { count(int id) : id(id) { }
void operator()() { for (int i = 0; i < 10; ++i) { boost::mutex::scoped_lock lock(io_mutex); // lock io, will be explained soon. std::cout << id << ": " << i << std::endl; } }
int id; };
int main(int argc, char* argv[]) { boost::thread thrd1(count(1)); boost::thread thrd2(count(2)); thrd1.join(); thrd2.join(); return 0; } 3、无需将类设计成一个functor,借助bind来构造functor对象以创建工作线程 #include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/bind.hpp> #include <iostream>
boost::mutex io_mutex;
struct count { static int num; int id;
count() : id(num++) {}
int do_count(int n) { for (int i = 0; i < n; ++i) { boost::mutex::scoped_lock lock(io_mutex); std::cout << id << ": " << i << std::endl; } return id; } };
int count::num = 1;
int main(int argc, char* argv[]) { count c1; boost::thread thrd1(boost::bind(&count::do_count, &c1, 10)); thrd1.join(); return 0; } 其中bind是一个函数模板,它可以根据后面的实例化参数构造出一个functor来,上面的boost::bind(&count::do_count, &c1, 10)其实等价于返回了一个functor: struct countFunctor { int operator() () { (&c1)->do_count(10); // just a hint, not actual code } }; 因此,以后就跟2中是一样的了。
|
|
相关文章:相关软件: |
|