日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【Boost】boost库中thread多线程详解10——condition条件变量

發布時間:2024/4/11 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Boost】boost库中thread多线程详解10——condition条件变量 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

有的時候僅僅依靠鎖住共享資源來使用它是不夠的。有時候共享資源只有某些狀態的時候才能夠使用。比方說,某個線程如果要從堆棧中讀取數據,那么如果棧中沒有數據就必須等待數據被壓棧。這種情況下的同步使用互斥體是不夠的。另一種同步的方式--條件變量,就可以使用在這種情況下。條件變量的使用總是和互斥體及共享資源聯系在一起的。線程首先鎖住互斥體,然后檢驗共享資源的狀態是否處于可使用的狀態。如果不是,那么線程就要等待條件變量。要指向這樣的操作就必須在等待的時候將互斥體解鎖,以便其他線程可以訪問共享資源并改變其狀態。它還得保證從等到得線程返回時互斥體是被上鎖得。當另一個線程改變了共享資源的狀態時,它就要通知正在等待條件變量得線程,并將之返回等待的線程。List4是一個使用了boost::condition的簡單例子。有一個實現了有界緩存區的類和一個固定大小的先進先出的容器。由于使用了互斥體boost::mutex,這個緩存區是線程安全的。put和get使用條件變量來保證線程等待完成操作所必須的狀態。有兩個線程被創建,一個在buffer中放入100個整數,另一個將它們從buffer中取出。這個有界的緩存一次只能存放10個整數,所以這兩個線程必須周期性的等待另一個線程。為了驗證這一點,put和get在std::cout中輸出診斷語句。最后,當兩個線程結束后,main函數也就執行完畢了。

#include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/condition.hpp> #include <iostream>const int BUF_SIZE = 10; const int ITERS = 100;boost::mutex io_mutex;class buffer {public:typedef boost::mutex::scoped_lockscoped_lock;buffer(): p(0), c(0), full(0){}void put(int m){scoped_lock lock(mutex);if (full == BUF_SIZE){{boost::mutex::scoped_locklock(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_locklock(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_locklock(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_locklock(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; }

? ? 當需要線程等待某個事物時,可以創建一個condition對象,然后通過這個對象來通知那些等待的線程。

#include <iostream> #include <boost/thread/thread.hpp> #include <boost/thread/condition.hpp> #include <boost/thread/mutex.hpp> #include <list> #include <string>class Request { /*...*/ };// A simple job queue class; don't do this, use std::queue template<typename T> class JobQueue { public:JobQueue( ) {}~JobQueue( ) {}void submitJob(const T& x) {boost::mutex::scoped_lock lock(mutex_);list_.push_back(x);workToBeDone_.notify_one( );}T getJob( ) {boost::mutex::scoped_lock lock(mutex_);workToBeDone_.wait(lock);// Wait until this condition is// satisfied, then lock the mutexT tmp = list_.front( );list_.pop_front( );return(tmp);}private:std::list<T> list_;boost::mutex mutex_;boost::condition workToBeDone_; };JobQueue<Request> myJobQueue;void boss( ) {for (;;) {// Get the request from somewhereRequest req;myJobQueue.submitJob(req);} }void worker( ) {for (;;) {Request r(myJobQueue.getJob( ));// Do something with the job...} }int main( ) {boost::thread thr1(boss);boost::thread thr2(worker);boost::thread thr3(worker);thr1.join( );thr2.join( );thr3.join( ); }boost::mutex::scoped_lock lock(mutex_); workToBeDone_.wait(lock);

???? 這兩行代碼,第一行鎖定這個mutex對象。第二行代碼解開這個mutex上的鎖,然后進行等待或者休眠,直到它的條件得到了滿足。這個mutex互斥對象的解鎖讓其他的線程能夠使用這個mutex對象,它們中的某個需要設置這個等待條件,之后通知另外的線程。

??? notify_all函數,通知那些所有正在等待某個條件變為真的線程,那些線程隨后進入運行狀態。wait方法做兩件事情:它一直等待直到有人在它正等待的condition上調用notify_one或notify_all,然后它就試圖鎖定相關的mutex。當調用的是notify_all時,盡管多個等待的線程都盡量去獲得下一個鎖,但誰將獲得依賴于這個mutex的類型和使用的優先策略。

??? 一個condition對象能讓消費者線程休眠,因此在還沒有碰到一個condition時處理器可以去處理別的事情。例如一個web服務器使用一個工作線程池來處理進來的請求。當沒有需求進來時,讓這些子線程處于等待狀態比讓它們循環的查詢或者睡眠然后偶爾喚醒來檢查這個隊列,要好很多。


總結

以上是生活随笔為你收集整理的【Boost】boost库中thread多线程详解10——condition条件变量的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。