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;  
    }
  • 相关阅读:
    tab切换与表格展示
    ajax
    api
    slice() 方法
    iframe跳转
    快排序
    【问题排查】cpu占用过高排查
    LOJ6013 负载平衡 [最小费用最大流]
    随机序列 [思维题, 组合数]
    P1777 帮助 [状压dp]
  • 原文地址:https://www.cnblogs.com/happykoukou/p/7019304.html
Copyright © 2011-2022 走看看