boost之并发编程

来源:互联网 发布:真有外星人吗 知乎 编辑:程序博客网 时间:2024/06/05 23:48

1.      Thread创建方法:(注意bind和thread以函数作为参数时,如果函数是静态成员函数或者普通函数,可以传函数名func或函数名取地址&func,但是如果是非静态成员函数,必须传函数名取地址)

1)     利用普通函数创建线程,例如:boost::thread thrd(&func,2);或boost::threadthrd(func,2);

2)     利用静态成员函数创建线程,例如:boost::threadthrd(&Base::static_func,2);或boost::thread thrd(Base:: static_func,2);

3)     利用非静态成员函数创建线程,例如:boost::threadthrd(&Base::func, pointer,2);

4)     利用函数对象也可以创建线程

例如利用bind实现回调函数注册:

class B{public:    void FuncB(int n){        std::cout<<"Func B:"<<n<<std::endl;    }};class A{public:    void start(){        for(int i = 0; i < 1000; ++i){            this_thread::sleep(boost::posix_time::milliseconds(1000));            m_callHandler(i);        }    }    template<class Callable, class A>    void registerHandler(Callable call, A a){        m_callHandler = boost::bind(call, a, _1);    }    template<class Callable>    void registerHandler(Callable call){        m_callHandler = boost::bind(call, _1);    }private:    callFuncInt_t m_callHandler;};

2.      Mutex的分类(一般结合lock模板使用):

1)     mutex, try_mutex为独占型互斥量,后者和mutex为同义词,兼容以前版本 

2)     timed_mutex 为定时独占型,增加了提供超时锁定功能,比 mutex多了两个成员函数:try_lock_for()和try_lock_until()

3)     recursive_mutex为递归型互斥量,支持多次锁定,并进行相应的多次解锁,可以减少死锁的概率。而mutex如果在一个线程中在执行中需要再次获得锁的情况,就会死锁。recursive_try_mutex后者和mutex为同义词,兼容以前版本 

4)     recursive_timed_mutex为定时递归型。其实就是timed_mutex和recursvie_mutex的组合版本

5)     shared_mutex为共享型互斥量,shared_mutex除了提供lock和unlock方法外,还有shared_lock和shared_unlock方法,允许多个(读者)线程同时加锁、解锁

6)     upgrade_mutex为升级互斥量,可以在任何时候升级为独占型互斥量,如果没当时没有现成拥有共享权限,即可立即获得独占权限。以下是原文解释:Thethread with upgradable ownership may at any time attempt to upgrade thatownership to exclusive ownership. If no other threads have shared ownership,the upgrade is completed immediately, and the thread now has exclusiveownership, which must be relinquished by a call to unlock()

3.      lock模版分类:

1)     lock_guard<T>:简单的独占锁,比boost::unique_lock更轻量级的lock,只有两个public方法,即构造和析构函数,不提供提前unlock的功能。

2)     unique_lock<T>:独占锁,unique_lock<T>对T没有限制,如果T是shared_mutex,则在执行加锁和解锁时会调用shared_lock和shared_unlock方法,否则,则执行一般的lock和unlock方法

3)     shared_lock<T>:共享锁,shared_lock<T>只允许T是shared_mutex

4)     scoped_lock:位于mutex::scoped_lock,其实就是typedefunique_lock<mutex> scoped_lock;

5)     upgrade_lock<T>:升级锁,不常用,暂时没有遇到使用场景

4.      条件变量:condition_variable_any 介绍与condition_variable类似,只不过condition_variable_any的 wait 函数可以接受任何lockable参数,而condition_variable只能接受std::unique_lock类型的参数,除此以外,和condition_variable几乎完全一样

例如利用互斥量、锁和条件变量实现生产着消费者问题:

class Buffer{public:    Buffer(int nSize = 0):m_read(0),m_nCapacity(nSize){    }    void get(int& x){        {        boost::shared_lock<shared_mutex> lock(m_mutex);        while(m_read == 0){            {                mutex::scoped_lock guard(io_mutex);                std::cout<<"empty waiting ..."<<std::endl;            }            m_conditionGet.wait(lock);        }        x = m_stack.top();        --m_read;        m_stack.pop();        }        m_conditionPut.notify_one();    }    void put(int x){        {        boost::unique_lock<shared_mutex> lock(m_mutex);        while(m_read == m_nCapacity){            {                mutex::scoped_lock guard(io_mutex);                std::cout<<"full waiting ..."<<std::endl;            }            m_conditionPut.wait(lock);        }        m_stack.push(x);        ++m_read;        }        m_conditionGet.notify_one();    }private:    boost::condition_variable_any m_conditionPut;    boost::condition_variable_any m_conditionGet;    boost::shared_mutex           m_mutex;    int                           m_nCapacity;    std::stack<int>                    m_stack;    int                           m_read;};Buffer buf(5);void producer(int n){    for(int i = 0; i < n; ++i){        {            mutex::scoped_lock guard(io_mutex);            std::cout<<"put: "<<i<<std::endl;        }        buf.put(i);    }}void consumer(int n){    int x = 0;    for(int i = 0; i < n; ++i){        buf.get(x);        mutex::scoped_lock guard(io_mutex);        std::cout<<"get: "<<x<<std::endl;    }}

5. future用来获取异步任务的结果,因此可以把它当成一种简单的线程间同步的手段。通过async或packaged_task启动的方法都可以利用future来获取任务的执行结果与状态。注意Future中的get方法会阻塞当前调用者线程直到结果返回。

例如:

int funcDelay(){    std::cout<<"start delay..."<<std::endl;    this_thread::sleep(boost::posix_time::millisec(5000));    std::cout<<"end delay..."<<std::endl;    return 1;}int main(int argc, char *argv[]){    unique_future<int> fu = boost::async(funcDelay);//    this_thread::sleep(boost::posix_time::millisec(6000));    try{        fu.get();    }catch(const std::exception& e){            std::cout<<e.what()<<std::endl;    }    std::cout<<"no delay..."<<std::endl;    return 0;}
程序会阻塞主线程,直到get()返回。

1 0
原创粉丝点击