• Boost::thread库的使用


    Boost::thread库的使用

    2009/11/26

    Kagula

    最后更新日期

    2016/12/02

    阅读对象

    本文假设读者有几下Skills

    [1]在C++中至少使用过一种多线程开发库,有Mutex和Lock的概念。

    [2]熟悉C++开发,在开发工具中,能够编译、设置boost::thread库。

    环境

    [1]Visual Studio 2005/2008 with SP1

    [2]boost1.39/1.40

    概要

    通过实例介绍boost thread的使用方式,本文主要由线程启动、Interruption机制、线程同步、等待线程退出、Thread Group几个部份组成。

    正文

    线程启动

    线程可以从以下四种方式启动:

    第一种用struct结构的operator成员函数启动:

    struct callable

    {

       void operator()() {  这里略去若干行代码   }

    };

    这里略去若干行代码

    Callable x;

    Boost::thread t(x);

    第二种以非成员函数形式启动线程

     void  func(int nP)

     {  这里略去若干行代码

    }

    这里略去若干行代码

    Boost::thread  t(func,123);

    第三种以成员函数形式启动线程

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

    第四种以Lambda表达方式启动

    [cpp] view plain copy
     
    1. boost::thread t([](int nVal)  
    2. {  
    3.     cout << nVal << " from thread" << endl;  
    4. },1000);  
    5.   
    6. t.join();  


     

    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不会中断当前线程。

    线程同步

    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;

    }

     

    http://blog.csdn.net/lee353086/article/details/4673790

  • 相关阅读:
    讨论Android开发中的MVC设计思想
    关于AppFromwork集成XMPP开发的使用详解
    Android 强大的开发支持库组件AppFromwork框架详解
    Z语音概述from百度
    《软件形式规格说明语言-Z》 缪淮扣 学习笔记 10-12
    形式化规格技术和验证技术小结
    编译TS发生 Property or signature expected
    electron 启动错误
    java学习第三章4.运算
    java学习第三章3.基本类型的转换和直接量
  • 原文地址:https://www.cnblogs.com/findumars/p/7635925.html
Copyright © 2020-2023  润新知