• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 311, comments - 0, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            寫過多線程程序的人都知道,不能讓多個(gè)線程同時(shí)訪問共享的資源是至關(guān)重要的。假如一個(gè)線程試圖改變共享數(shù)據(jù)的值,而另外一個(gè)線程試圖去讀取該共享數(shù)據(jù)的值,結(jié)果將是未定義的。為了阻止這樣的事情發(fā)生,需要用到一些非凡的原始數(shù)據(jù)類型和操作。其中最重的一個(gè)就是總所周知的mutex(“mutual exclusion”的縮寫。譯注:相互排斥的意思,經(jīng)常被翻譯為互斥體”)。mutex在同一時(shí)間只能答應(yīng)一個(gè)線程訪問共享資源。當(dāng)一個(gè)線程需要訪問共享資源時(shí),它必須先鎖住”mutex,假如任何其他線程已經(jīng)鎖住了mutex,那么本操作將會(huì)一直被阻塞,直到鎖住了mutex的線程解鎖,這就保證了共享資源,在同一時(shí)間,只有一個(gè)線程可以訪問。

            mutex的概念有幾個(gè)變種。Boost.Threads支持兩大類型的mutex:簡單mutex和遞歸mutex。一個(gè)簡單的mutex只能被鎖住一次,假如同一線程試圖兩次鎖定mutex,將會(huì)產(chǎn)生死鎖。對(duì)于遞歸mutex,一個(gè)線程可以多次鎖定一個(gè)mutex,但必須以同樣的次數(shù)對(duì)mutex進(jìn)行解鎖,否則其他線程將無法鎖定該mutex。

            在上述兩大類mutex的基礎(chǔ)上,一個(gè)線程如何鎖定一個(gè)mutex也有些不同變化。一個(gè)線程有3種可能方法來鎖定mutex

            1. 等待并試圖對(duì)mutex加鎖,直到?jīng)]有其他線程鎖定mutex;

            2. 試圖對(duì)mutex加鎖,并立即返回,假如其他線程鎖定了mutex;

            3. 等待并試圖對(duì)mutex加鎖,直到?jīng)]有其他線程鎖定mutex或者直到規(guī)定的時(shí)間已過。

            看起來最好的mutex類型是遞歸的mutex了,因?yàn)樯鲜?/span>3種加鎖的方式它都支持。不過,不同的加鎖方式有不同的消耗,因此對(duì)于特定的應(yīng)用,Boost.Threads答應(yīng)你挑選最有效率的mutex。為此,Boost.Threads提供了6中類型的mutex,效率由高到低排列:boost::mutexboost::try_mutex,boost::timed_mutexboost::recursive_mutex,boost::recursive_try_mutexboost::recursive_timed_mutex

            假如一個(gè)線程鎖定一個(gè)mutex后,而沒有解鎖,就會(huì)發(fā)生死鎖,這也是最為常見的錯(cuò)誤了,為此,Boost.Threads專門進(jìn)行了設(shè)計(jì),可不直接對(duì)mutex加鎖或者解鎖操作,以使這種錯(cuò)誤不可能發(fā)生(或至少很難發(fā)生)。取而代之地,mutex類定義了內(nèi)嵌的typedef來實(shí)現(xiàn)RAII(Resource Acquisition In Initialization,譯注:在初始化時(shí)資源獲得)[4]用以對(duì)一個(gè)mutex進(jìn)行加鎖或者解鎖,這就是所謂的Scoped Lock模式。要構(gòu)建一個(gè)這種類型的鎖,需要傳送一個(gè)mutex引用,構(gòu)造函數(shù)將鎖定mutex,析構(gòu)函數(shù)將解鎖mutexC++語言規(guī)范確保了析構(gòu)函數(shù)總是會(huì)被調(diào)用,所以即使有異常拋出,mutex也會(huì)被正確地解鎖。

            這種模式確保了mutex的正確使用。不過必須清楚,盡管Scoped Lock模式保證了mutex被正確解鎖,但它不能保證在有異常拋出的時(shí)候,所有共享資源任然處于有效的狀態(tài),所以,就像進(jìn)行單線程編程一樣,必須確保異常不會(huì)讓程序處于不一致的狀態(tài)。同時(shí),鎖對(duì)象不能傳送給另外一個(gè)線程,因?yàn)樗麄兯S護(hù)的狀態(tài)不會(huì)受到此種用法的保護(hù)。

            列表2舉例說明了boost::mutex類的一個(gè)簡單的用法。其中兩個(gè)線程被創(chuàng)建,每個(gè)循環(huán)10次,將id和當(dāng)前循環(huán)計(jì)數(shù)輸出到std::coutmain線程等待著兩個(gè)線程結(jié)束。std::cout對(duì)象是一個(gè)共享資源,所以每個(gè)線程均使用全局mutex,以確保在同一時(shí)刻,只有一個(gè)線程輸出到它。

            #include <boost/thread/thread.hpp>

            #include <boost/thread/mutex.hpp>

            #include <iostream>

            boost::mutex io_mutex;

            struct count

            {

            count(int id) : id(id) { }

            void operator()()

            {

            for (int i = 0; i < 10; ++i)

            {

            boost::mutex::scoped_lock lock(io_mutex);

            std::cout << id << ": " << i << std::endl;

            }

            }

            int id;

            };

            int main(int argc, char* argv[])

            {

            boost::thread thrd1(count(1));

            boost::thread thrd2(count(2));

            thrd1.join();

            thrd2.join();

            return 0;

            }

            列表2

            也許你已經(jīng)注重到在列表2的代碼中,需要手工寫一個(gè)函數(shù)對(duì)象,才能向線程傳送數(shù)據(jù)。盡管代碼很簡單,但每次都要寫這樣的代碼也會(huì)讓人有單調(diào)沉悶之感。有另外一種更輕易的解決辦法,Functional庫可以讓你通過將需要傳入的數(shù)據(jù)綁定到另外一個(gè)函數(shù)對(duì)象的方式,來創(chuàng)建一個(gè)新的函數(shù)對(duì)象。列表3展現(xiàn)了Boost.Bind庫如何不寫函數(shù)對(duì)象,而簡化列表2中的代碼。

            // This program is identical to listing2.cpp except that it uses

            // Boost.Bind to simplify the creation of a thread that takes data.

            #include <boost/thread/thread.hpp>

            #include <boost/thread/mutex.hpp>

            #include <boost/bind.hpp>

            #include <iostream>

            boost::mutex io_mutex;

            void count(int id)

            {

            for (int i = 0; i < 10; ++i)

            {

            boost::mutex::scoped_lock lock(io_mutex);

            std::cout << id << ": " << i << std::endl;

            }

            }

            int main(int argc, char* argv[])

            {

            boost::thread thrd1(boost::bind(&count, 1)); // 有無&符號(hào)均可

            boost::thread thrd2(boost::bind(&count, 2)); // 有無&符號(hào)均可

            thrd1.join();

            thrd2.join();

            return 0;

            }

            列表3

            久久se精品一区二区| 99久久国产热无码精品免费久久久久| 少妇久久久久久被弄到高潮| 亚洲伊人久久成综合人影院| 国内精品伊人久久久久AV影院| 久久国产成人精品国产成人亚洲| 伊人久久大香线蕉亚洲五月天| 99国产精品久久| 久久精品无码一区二区WWW| 色综合久久综合网观看| 久久精品免费全国观看国产| 久久免费精品视频| 久久夜色精品国产噜噜麻豆| 欧洲国产伦久久久久久久| 欧美精品一区二区精品久久| 亚洲乱码精品久久久久..| 色天使久久综合网天天| 久久中文字幕一区二区| 久久久久久久97| 亚洲AV无码久久精品蜜桃| 伊色综合久久之综合久久| 久久精品国产亚洲7777| 久久精品国产99国产精偷 | 久久成人国产精品| 久久丫忘忧草产品| 久久久噜噜噜久久| 久久国产三级无码一区二区| 婷婷综合久久狠狠色99h| 久久精品国产亚洲AV高清热| 亚洲AV无码久久精品狠狠爱浪潮| 色妞色综合久久夜夜| 香蕉久久夜色精品国产2020 | 欧美国产成人久久精品| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | A狠狠久久蜜臀婷色中文网| 少妇久久久久久久久久| 国产福利电影一区二区三区久久老子无码午夜伦不| 99久久国产主播综合精品| 精品伊人久久久| 久久福利青草精品资源站免费| 久久久久人妻一区二区三区vr |