zoukankan      html  css  js  c++  java
  • 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;  
    }
  • 相关阅读:
    广域网(ppp协议、HDLC协议)
    0120. Triangle (M)
    0589. N-ary Tree Preorder Traversal (E)
    0377. Combination Sum IV (M)
    1074. Number of Submatrices That Sum to Target (H)
    1209. Remove All Adjacent Duplicates in String II (M)
    0509. Fibonacci Number (E)
    0086. Partition List (M)
    0667. Beautiful Arrangement II (M)
    1302. Deepest Leaves Sum (M)
  • 原文地址:https://www.cnblogs.com/happykoukou/p/7019304.html
Copyright © 2011-2022 走看看