<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    Boost Thread學習筆記二

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    除了thread,boost::thread另一個重要組成部分是mutex,以及工作在mutex上的boost::mutex::scoped_lock、condition和barrier,這些都是為實現線程同步提供的。

    mutex
    boost提供的mutex有6種:
    boost::mutex
    boost::try_mutex
    boost::timed_mutex
    boost::recursive_mutex
    boost::recursive_try_mutex
    boost::recursive_timed_mutex
    下面僅對boost::mutex進行分析。
    mutex類是一個CriticalSection(臨界區)封裝類,它在構造函數中新建一個臨界區并InitializeCriticalSection,然后用一個成員變量
    void
    * m_mutex;
    來保存該臨界區結構。
    除 此之外,mutex還提供了do_lock、do_unlock等方法,這些方法分別調用EnterCriticalSection、 LeaveCriticalSection來修改成員變量m_mutex(CRITICAL_SECTION結構指針)的狀態,但這些方法都是private的,以防止我們直接對mutex進行鎖操作,所有的鎖操作都必須通過mutex的友元類detail::thread::lock_ops<mutex>來完成,比較有意思的是,lock_ops的所有方法:lock、unlock、trylock等都是static的,如lock_ops<Mutex>::lock的實現:

     1 template <typename Mutex>
     2 class lock_ops : private noncopyable
     3 {
     4 RFID設備管理軟件
     5 public:
     6     static void lock(Mutex& m)
     7     {
     8         m.do_lock();
     9     }
    10 RFID設備管理軟件
    11 }

    boost::thread的設計者為什么會這么設計呢?我想大概是:
    1
    、boost::thread的設計者不希望被我們直接操作mutex,改變其狀態,所以mutex的所有方法都是private的(除了構造函數,析構函數)。
    2
    、雖然我們可以通過lock_ops來修改mutex的狀態,如:

     1 #include <boost/thread/thread.hpp>
     2 #include <boost/thread/mutex.hpp>
     3 #include <boost/thread/detail/lock.hpp>
     4 
     5 int main()
     6 {
     7     boost::mutex mt;
     8     //mt.do_lock();        // Error! Can not access private member!
     9 
    10     boost::detail::thread::lock_ops<boost::mutex>::lock(mt);
    11 
    12     return 0;
    13 }

    但是,這是不推薦的,因為mutex、scoped_lock、condition、barrier是一套完整的類系,它們是相互協同工作的,像上面這么操作沒有辦法與后面的幾個類協同工作。
    scoped_lock
    上面說過,不應該直接用lock_ops來操作mutex對象,那么,應該用什么呢?答案就是scoped_lock。與存在多種mutex一樣,存在多種與mutex對應的scoped_lock:

    scoped_lock
    scoped_try_lock
    scoped_timed_lock

    這里我們只討論scoped_lock。
    scoped_lock是定義在namespace boost::detail::thread下的,為了方便我們使用(也為了方便設計者),mutex使用了下面的typedef
    typedef
     detail::thread::scoped_lock<mutex> scoped_lock;
    這樣我們就可以通過:
    boost::mutex::scoped_lock
    來使用scoped_lock類模板了。
    由于scoped_lock的作用僅在于對mutex加鎖/解鎖(即使mutex EnterCriticalSection/LeaveCriticalSection),因此,它的接口也很簡單,除了構造函數外,僅有lock/unlock/locked(判斷是否已加鎖),及類型轉換操作符void*,一般我們不需要顯式調用這些方法,因為scoped_lock的構造函數是這樣定義的:

    1 explicit scoped_lock(Mutex& mx, bool initially_locked=true)
    2     : m_mutex(mx), m_locked(false)
    3 {
    4     if (initially_locked) lock();
    5 }


    注:m_mutex是一個mutex的引用。
    因此,當我們不指定initially_locked參數構造一個scoped_lock對象 時,scoped_lock會自動對所綁定的mutex加鎖,而析構函數會檢查是否加鎖,若已加鎖,則解鎖;當然,有些情況下,我們可能不需要構造時自動 加鎖,這樣就需要自己調用lock方法。后面的condition、barrier也會調用scoped_lock的lock、unlock方法來實現部 分方法。
    正因為scoped_lock具有可在構造時加鎖,析構時解鎖的特性,我們經常會使用局部變量來實現對mutex的獨占訪問。

     1 #include <boost/thread/thread.hpp>
     2 #include <boost/thread/mutex.hpp>
     3 #include <iostream>
     4 
     5 boost::mutex io_mutex;
     6 
     7 void count()    // worker function
     8 {
     9     for (int i = 0; i < 10; ++i)
    10     {
    11         boost::mutex::scoped_lock lock(io_mutex);
    12         std::cout << i << std::endl;
    13     }
    14 }
    15 
    16 int main(int argc, char* argv[])
    17 {
    18     boost::thread thrd1(&count);
    19     boost::thread thrd2(&count);
    20     thrd1.join();
    21     thrd2.join();
    22 
    23     return 0;
    24 }


    在每次輸出信息時,為了防止整個輸出過程被其它線程打亂,通過對io_mutex加鎖(進入臨界區),從而保證了輸出的正確性。
    在使用 scoped_lock時,我們有時候需要使用全局鎖(定義一個全局mutex,當需要獨占訪問全局資源時,以該全局mutex為參數構造一個 scoped_lock對象即可。全局mutex可以是全局變量,也可以是類的靜態方法等),有時候則需要使用對象鎖(將mutex定義成類的成員變 量),應該根據需要進行合理選擇。
    Java的synchronized可用于對方法加鎖,對代碼段加鎖,對對象加鎖,對類加鎖(仍然是對象級 的),這幾種加鎖方式都可以通過上面講的對象鎖來模擬;相反,在Java中實現全局鎖好像有點麻煩,必須將請求封裝到類中,以轉換成上面的四種 synchronized形式之一。

    condition
    condition的接口如下:

     1 class condition : private boost::noncopyable   // Exposition only
     2 {
     3 public:
     4   // construct/copy/destruct
     5   condition();
     6   ~condition();
     7 
     8   // notification
     9   void notify_one();
    10   void notify_all();
    11 
    12   // waiting
    13   template<typename ScopedLock> void wait(ScopedLock&);
    14   template<typename ScopedLock, typename Pred> void wait(ScopedLock&, Pred);
    15   template<typename ScopedLock>
    16     bool timed_wait(ScopedLock&, const boost::xtime&);
    17   template<typename ScopedLock, typename Pred>
    18     bool timed_wait(ScopedLock&, Pred);
    19 };


    其中wait用于等待某個condition的發生,而timed_wait則提供具有超時的wait功能,notify_one用于喚醒一個等待該condition發生的線程,notify_all則用于喚醒所有等待該condition發生的線程。

    由于condition的語義相對較為復雜,它的實現也是整個boost::thread庫中最復雜的(對Windows版本而言,對支持pthread的版本而言,由于pthread已經提供了pthread_cond_t,使得condition實現起來也十分簡單),下面對wait和notify_one進行簡要分析。
    condition內部包含了一個condition_impl對象,由該對象執行來處理實際的wait、notify_one...等操作。

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全