背景

•       今天互联网应用服务程序普遍使用多线程来提高与多客户链接时的效率;为了达到最大的吞吐量,事务服务器在单独的线程上运行服务程序;

GUI应用程序将那些费时,复杂的处理以线程的形式单独运行,以此来保证用户界面能够及时响应用户的操作。这样使用多线程的例子还有很多。

•       跨平台

创建线程

•       头文件

namespace boost {

class thread;

class thread_group;

}

•       thread():构造一个表示当前执行线程的线程对象

•       explicit thread(const boost::function0& threadfunc)

注:boost::function0可以简单看为:一个无返回(返回void),无参数的函数。这里的函数也可以是类重载operator()构成的函数。

第一种方式:最简单方法

•       #include

•       #include

•       void hello()

•       {

•               std::cout <<

•               "Hello world, I''m a thread!"

•               << std::endl;

•       }

•       int main(int argc, char* argv[])

•       {

•               boost::thread thrd(&hello);

•               thrd.join();

•               return 0;

•       }

第二种方式:复杂类型对象作为参数来创建线程

•       #include

•       #include

•       #include

•       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);

•                               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;

•       }

第三种方式:在类内部创建线程

•       (1)类内部静态方法启动线程

•       #include

•       #include

•       class HelloWorld

•       {

•       public:

•       static void hello()

•       {

•             std::cout <<

•             "Hello world, I''m a thread!"

•             << std::endl;

•       }

•       static void start()

•       {

•        boost::thread thrd( hello );

•        thrd.join();

•       }

•       };

•       int main(int argc, char* argv[])

•       {

•       HelloWorld::start();

•       return 0;

•       }

•       在这里start()和hello()方法都必须是static方法。

•       (2)如果要求start()和hello()方法不能是静态方法则采用下面的方法创建线程:

•       #include

•       #include

•       #include

•       class HelloWorld

•       {

•       public:

•       void hello()

•       {

•           std::cout <<

•           "Hello world, I''m a thread!"

•           << std::endl;

•       }

•       void start()

•       {

•        boost::function0< void> f = boost::bind(&HelloWorld::hello,this);

•        boost::thread thrd( f );

•        thrd.join();

•       }

•       };

•       int main(int argc, char* argv[])

•       {

•       HelloWorld hello;

•       hello.start();

•       return 0;

•       }

•       (3)在Singleton模式内部创建线程:

•       #include

•       #include

•       #include

•       class HelloWorld

•       {

•       public:

•       void hello()

•       {

•           std::cout <<

•           "Hello world, I''m a thread!"

•           << std::endl;

•       }

•       static void start()

•       {

•        boost::thread thrd( boost::bind

•                          (&HelloWorld::hello,&HelloWorld::getInstance() ) ) ;

•        thrd.join();

•       }

•       static HelloWorld& getInstance()

•       {

•        if ( !instance )

•             instance = new HelloWorld;

•        return *instance;

•       }

•       private:

•       HelloWorld(){}

•       static HelloWorld* instance;

•       };

•       HelloWorld* HelloWorld::instance = 0;

•       int main(int argc, char* argv[])

•       {

•       HelloWorld::start();

•       return 0;

•       }

第四种方法:用类内部函数在类外部创建线程

•       #include

•       #include

•       #include

•       #include

•       class HelloWorld

•       {

•       public:

•       void hello(const std::string& str)

•       {

•               std::cout <

•       }

•       };

•       int main(int argc, char* argv[])

•       {

•       HelloWorld obj;

•       boost::thread thrd( boost::bind(&HelloWorld::hello,&obj,"Hello

•                                      world, I''m a thread!" ) ) ;

•       thrd.join();

•       return 0;

•       }

如果线程需要绑定的函数有参数则需要使用boost::bind。比如想使用 boost::thread创建一个线程来执行函数:void f(int i),

如果这样写:boost::thread thrd(f)是不对的,因为thread构造函数声明接受的是一个没有参数且返回类型为void的型别,而且

不提供参数i的值f也无法运行,这时就可以写:boost::thread thrd(boost::bind(f,1))。涉及到有参函数的绑定问题基本上都

是boost::thread、boost::function、boost::bind结合起来使用。

互斥体

•       一个互斥体一次只允许一个线程访问共享区。当一个线程想要访问共享区时,首先要做的就是锁住(lock)互斥体。

•       Boost线程库支持两大类互斥体,包括简单互斥体(simple mutex)和递归互斥体(recursive mutex)。

有了递归互斥体,单个线程就可以对互斥体多次上锁,当然也必须解锁同样次数来保证其他线程可以对这个互斥体上锁。

•       Boost线程库提供的互斥体类型:

boost::mutex,

boost::try_mutex,

boost::timed_mutex,

boost::recursive_mutex,

boost::recursive_try_mutex,

boost::recursive_timed_mutex,

boost::shared_mutex

•       mutex类采用Scope Lock模式实现互斥体的上锁和解锁。即构造函数对互斥体加锁,析构函数对互斥体解锁。

•       对应现有的几个mutex导入了scoped_lock,scoped_try_lock,scoped_timed_lock.

•       scoped系列的特色就是析构时解锁,默认构造时加锁,这就很好的确定在某个作用域下某线程独占某段代码。

mutex+scoped_lock

•       #include

•       #include

•       #include

•       #include

•       boost::mutex   io_mutex;

•       void count(int id)

•       {

•              for (int i = 0; i < 10; ++i)

•              {

•                      boost::mutex::scoped_lock    lock(io_mutex);

•                      std::cout << id << ": " << i << std::endl;

•              }

•       }

•       int main(int argc, char* argv[])

•       {

•              boost::thread thrd1(boost::bind(&count, 1));

•              boost::thread thrd2(boost::bind(&count, 2));

•              thrd1.join();

•              thrd2.join();

•              return 0;

•       }

try_mutex+scoped_try_lock

•       void loop(void)

•       {

•              bool running = true;

•              while (running)

•              {

•                      static boost::try_mutex iomutex;

•                      {

•                              boost::try_mutex::scoped_try_lock    lock(iomutex);//锁定mutex

•                              if (lock.owns_lock())

•                              {

•                                     std::cout << "Get lock." << std::endl;

•                              }

•                              else

•                              {

•                                     // To do

•                                     std::cout << "Not get lock." << std::endl;

•                                     boost::thread::yield(); //释放控制权

•                                     continue;

•                              }

•                      } //lock析构,iomutex解锁

•              }

•       }

timed_mutex+scoped_timed_mutex

•       void loop(void)

•       {

•              bool running = true;

•              while (running)

•              {

•                      typedef boost::timed_mutex MUTEX;

•                      typedef MUTEX::scoped_timed_lock LOCK;

•                      static MUTEX iomutex;

•                      {

•                              boost::xtime xt;

•                              boost::xtime_get(&xt,boost::TIME_UTC);

•                              xt.sec += 1; //超时时间秒

•                              LOCK lock(iomutex, xt); //锁定mutex

•                              if (lock.owns_lock())

•                              {

•                                     std::cout << "Get lock." << std::endl;

•                              }

•                              else

•                              {

•                                     std::cout << "Not get lock." << std::endl;

•                                     boost::thread::yield(); //释放控制权

•                              }

•                              //::sleep(10000); //长时间

•                      } //lock析构,iomutex解锁

•                      //::sleep(250);

•              }

•       }

shared_mutex

•       应用boost::thread的shared_mutex实现singled_write/multi_read的简单例子

•       #include

•       #include

•       #include

•       using namespace std;

•       using namespace boost;

•       boost::shared_mutex shr_mutex;

•       /// 这个是辅助类,能够保证log_info被完整的输出

•       class safe_log {

•       public:

•           static void log(const std::string& log_info) {

•               boost::mutex::scoped_lock lock(log_mutex);

•               cout << log_info << endl;

•           }

•       private:

•           static boost::mutex log_mutex;

•       };

•       boost::mutex safe_log::log_mutex;

•       void write_process() {

•           shr_mutex.lock();

•           safe_log::log("begin of write_process");

•           safe_log::log("end of write_process");

•           shr_mutex.unlock();

•       }

•       void read_process() {

•           shr_mutex.lock_shared();

•           safe_log::log("begin of read_process");

•           safe_log::log("end of read_process");

•           shr_mutex.unlock_shared();

•       }

•       int main() {

•           thread_group threads;

•           for (int i = 0; i < 10; ++ i) {

•               threads.create_thread(&write_process);

•               threads.create_thread(&read_process);

•           }

•           threads.join_all();

•           ::system("PAUSE");

•           return 0;

•       }

条件变量

•       有的时候仅仅依靠锁住共享资源来使用它是不够的。有时候共享资源只有某些状态的时候才能够使用。

比方说,某个线程如果要从堆栈中读取数据,那么如果栈中没有数据就必须等待数据被压栈。这种情

况下的同步使用互斥体是不够的。另一种同步的方式--条件变量,就可以使用在这种情况下。

•       boost::condition

typedef condition_variable_any condition;

void wait(unique_lock& m);

•       boost::condition_variable

template

void wait(lock_type& m);

•       #include

•       #include

•       #include

•       #include

•       const int BUF_SIZE = 10;

•       const int ITERS = 100;

•       boost::mutex io_mutex;

•       class buffer

•       {

•       public:

•              typedef boost::mutex::scoped_lock scoped_lock;

•              buffer()

•              : p(0), c(0), full(0)

•              {

•              }

•              void put(int m)

•              {

•                      scoped_lock lock(mutex);

•                      if (full == BUF_SIZE)

•                      {

•                              {

•                                     boost::mutex::scoped_lock lock(io_mutex);

•                                     std::cout << "Buffer is full. Waiting..." << std::endl;

•                              }

•                              while (full == BUF_SIZE)

•                                     cond.wait(lock);

•                      }

•                      buf[p] = m;

•                      p = (p+1) % BUF_SIZE;

•                      ++full;

•                      cond.notify_one();

•              }

•              int get()

•              {

•                      scoped_lock lk(mutex);

•                      if (full == 0)

•                      {

•                              {

•                                     boost::mutex::scoped_lock lock(io_mutex);

•                                     std::cout << "Buffer is empty. Waiting..." << std::endl;

•                              }

•                              while (full == 0)

•                                     cond.wait(lk);

•                      }

•                      int i = buf[c];

•                      c = (c+1) % BUF_SIZE;

•                      --full;

•                      cond.notify_one();

•                      return i;

•              }

•       private:

•                      boost::mutex mutex;

•                      boost::condition cond;

•                      unsigned int p, c, full;

•                      int buf[BUF_SIZE];

•       };

•       buffer buf;

•       void writer()

•       {

•              for (int n = 0; n < ITERS; ++n)

•              {

•                      {

•                              boost::mutex::scoped_lock lock(io_mutex);

•                              std::cout << "sending: " << n << std::endl;

•                      }

•                      buf.put(n);

•              }

•       }

•       void reader()

•       {

•              for (int x = 0; x < ITERS; ++x)

•               {

•                      int n = buf.get();

•                      {

•                              boost::mutex::scoped_lock lock(io_mutex);

•                              std::cout << "received: " << n << std::endl;

•                      }

•              }

•       }

•       int main(int argc, char* argv[])

•       {

•              boost::thread thrd1(&reader);

•              boost::thread thrd2(&writer);

•              thrd1.join();

•              thrd2.join();

•              return 0;

•       }

线程局部存储

•       函数的不可重入。

•       Boost线程库提供了智能指针boost::thread_specific_ptr来访问本地存储线程(thread local storage)。

•       #include

•       #include

•       #include

•       #include

•       boost::mutex io_mutex;

•       boost::thread_specific_ptr ptr;

•       struct count

•       {

•              count(int id) : id(id) { }

•              void operator()()

•              {

•                      if (ptr.get() == 0)

•                              ptr.reset(new int(0));

•                      for (int i = 0; i < 10; ++i)

•                      {

•                              (*ptr)++; // 往自己的线程上加

•                              boost::mutex::scoped_lock lock(io_mutex);

•                              std::cout << id << ": " << *ptr << 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;

•       }

仅运行一次的例程

•       如何使得初始化工作(比如说构造函数)也是线程安全的。

•       “一次实现”(once routine)。“一次实现”在一个应用程序只能执行一次。

•       Boost线程库提供了boost::call_once来支持“一次实现”,并且定义了一个标志boost::once_flag及一个初始化这个标志的宏 BOOST_ONCE_INIT。

•       #include

•       #include

•       #include

•       int i = 0;

•       boost::once_flag flag = BOOST_ONCE_INIT;

•       void init()

•       {

•              ++i;

•       }

•       void thread()

•       {

•              boost::call_once(&init, flag);

•       }

•       int main(int argc, char* argv[])

•       {

•              boost::thread thrd1(&thread);

•              boost::thread thrd2(&thread);

•              thrd1.join();

•              thrd2.join();

•              std::cout << i << std::endl;

•              return 0;

•       }

Boost线程库的未来

•       Boost线程库正在计划加入一些新特性。其中包括boost::read_write_mutex,它可以让多个线程同时从共享区中读取数据,

但是一次只可能有一个线程向共享区写入数据;boost::thread_barrier,它使得一组线程处于等待状态,知道所有得线程

都都进入了屏障区;boost::thread_pool,他允许执行一些小的routine而不必每一都要创建或是销毁一个线程。

•       Boost线程库已经作为标准中的类库技术报告中的附件提交给C++标准委员会,它的出现也为下一版C++标准吹响了第一声号角。

委员会成员对 Boost线程库的初稿给予了很高的评价,当然他们还会考虑其他的多线程库。他们对在C++标准中加入对多线程的

支持非常感兴趣。从这一点上也可以看出,多线程在C++中的前途一片光明。

boost muti-thread的更多相关文章

  1. boost:thread使用实例

    /************************************************************************/ /*功能描述: boost thread使用实例 ...

  2. boost之thread

    1.boost里的thread创建之后会立即启动. 代码示例: #include <iostream> #include <string> #include <vecto ...

  3. boost库thread.hpp编译警告honored已修复

    请浏览:https://svn.boost.org/trac/boost/ticket/7874 #7874: compile warning: thread.hpp:342: warning: ty ...

  4. 关于boost的thread的mutex与lock的问题

    妈的,看了好久的相关的知识,感觉终于自己有点明白了,我一定要记下来啊,相关的知识呀.... 1, 也可以看一下boost的线程指南:http://wenku.baidu.com/link?url=E_ ...

  5. 【boost】MFC dll中使用boost thread的问题

    项目需要,在MFC dll中使用了boost thread(<boost/thread.hpp>),LoadLibraryEx的时候出现断言错误,去掉thread库引用后断言消失. 百度g ...

  6. Boost Thread学习笔记二

    除了thread,boost种:boost::mutexboost::try_mutexboost::timed_mutexboost::recursive_mutexboost::recursive ...

  7. boost thread 在非正常退出时 内存泄露问题

    在使用boost的thread库的时候,如果主程序退出,thread创建的线程不做任何处理,则会出现内存泄露. 解决方法: 在主线程退出时,对所有thread使用interrupt()命令,然后主程序 ...

  8. gcc boost版本冲突解决日记

    问题背景 项目在Ubuntu10 64位 boost 1.55,boost采用的是项目内包含相对目录的形式部署 项目采用了 -Wall -Wextra -Werror -Wconversion 最高的 ...

  9. boost库(条件变量)

    1相关理念 (1)类名 条件变量和互斥变量都是boost库中被封装的类. (2)条件变量 条件变量是thread库提供的一种等待线程同步的机制,可实现线程间的通信,它必须与互斥量配合使用,等待另一个线 ...

  10. Using Boost Libraries in Windows Store and Phone Applications

    Using Boost Libraries in Windows Store and Phone Applications RATE THIS Steven Gates 18 Jul 2014 5:3 ...

随机推荐

  1. js中判断json是否为空

    var jsonStr ={}; 1.判断json是否为空 jQuery.isEmptyObject(): 2.判断对象是否为空: 1.if   (typeOf(x)   ==   "und ...

  2. [书目20131223]Android、iPhone、Windows Phone手机网页及网站设计:最佳实践与设计精粹 - 张亚飞

    目录 第I篇 手机版专用网站设计和开发入门篇 第1章 准备创作环境和测试环境 3 1.1 使用Mobile Safari测试网页 4 1.1.1 iOS Simulator安装 5 1.1.2 使用M ...

  3. hdu-5505(数论)

    题目链接: GT and numbers Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Ot ...

  4. 有一种风格,叫做 Low Poly 3D

    原作:Simon阿文    杂交编辑者:RhinoC       个人更推崇使用第二款神器 ImageTriangulator :http://www.conceptfarm.ca/2013/port ...

  5. Python之Python Imaging Library

    document:http://effbot.org/imagingbook/pil-index.htm http://pillow.readthedocs.io/en/3.1.x/index.htm ...

  6. css改变谷歌浏览器的滚动条样式

    详细内容请点击 /*---滚动条默认显示样式--*/ ::-webkit-scrollbar-thumb{        height:50px;    outline-offset:-2px;   ...

  7. Charles 应用

    1.首先设置本机host文件,将需要测试的域名指向127.0.0.1:(测试域名没有代理,才会这么操作): 2.打开Charles,设置Proxy选项,取消“Windows Proxy”选中状态: 3 ...

  8. AngularJS尝鲜一

    第一个小例子,体验一下: <!DOCTYPE html> <html> <head> <title>Index</title> </h ...

  9. XAML

    XAML定义 XAML是一种相对简单.通用的声明式编程语言,它适合于构建和初始化.NET对象. XAML仅仅是一种使用.NET API的方式,把它与HTML.可伸缩向量图形(SVG)或其他特定领域的格 ...

  10. windows下部署 ISCSI存储

    Write bt xiaoyang 配置篇 这里使用的软件为iscsiTargetqfe 1.      首先安装软件,可在微软官网下载 2.      然后找到安装程序 3.      完成安装后打 ...