Boostライブラリ学習(3)thread 2

2745 ワード

反発ロック
マルチスレッドプログラミングで基本的に使われるもの.スレッドaとスレッドbがデータXにアクセスする場合、すべてのアクセスデータXの場所で反発ロックで保護され、そのうちの1つのスレッドに反発ロック保護を加えるだけでは役に立たない.(1つの場合のみ、1つのスレッドのみがデータを修正し、他のスレッドがデータのみを読み取る場合、データを修正するスレッドは、読み出し時に書き込み操作が同時に存在しないため、読み出し時にロックを追加する必要はありません.たとえば、スレッドaはデータXを読み書きし、スレッドbはデータXのみを読み書きする場合、スレッドaはデータを読むときにロック保護を追加しないことができます.)
反発ロックの種類
  • mutexとrecursive_mutexがサポートする方法はlock(),try_lock(),unlock().try_lockはすぐに戻ります(成功するか失敗するかもしれません)、lockは成功(つまり他の人のunlock)を待ってから戻ります.recursive_mutexはmutexと比較して、同じスレッドに複数回ロックをかけることができます.主にロック後に別の関数を呼び出すために使用され、呼び出されたこの関数では同じmutexに対してロック処理が行われる.この場合,mutexを用いると,内層関数におけるlock()処理時にデッドロックが発生する.
  • timed_mutexとrecursive_timed_mutexがサポートする方法は、前の方法より2つ多く、try_lock_for()とtry_lock_until().多く出た2つの関数とtry_ロック機能は、すぐに戻るのではなく、成功またはTimeOutまで待つだけです.recursive_timed_mutexとtimed_mutexの違い、recursive_mutextとmutexの差は同じです.反発ロックツールクラスが実際にコードを記述する場合、上記の各種反発ロックを直接使用することは推奨されません.原因は簡単で、直接反発ロックを使用すると、様々な異常が発生した場合、反発ロックが解放されることを保証する必要があります.反発ロックを使用するツールクラスではこの問題はなく、ツールクラスオブジェクトが解放されると自動的に反発ロックが解放されます.
  • lock_guardのオブジェクトは、生存中(宣言から変数が回収されるまで)反発ロック状態にある.申明には2つの形式がある:boost::lock_guard lg(Lockable &m);//申明時にlock boost::lock_を呼び出すguard lg(Lockable &m,boost::adopt_lock);//反発ロックmがlockに成功した状態であることを示す
  • unique_guardのオブジェクトは、生存中にロックと非ロックの状態を複数回切り替えることができます.申明には5つの形式がある:boost::unique_lock ul(Lockable &m);//とlock_guardの方式は同じboost::unique_lock ul(Lockable &m,boost::adopt_lock);//とlock_guardの方式2同じboost::unique_lock ul(Lockable &m,boost::defer_lock);//ただし、lockシリーズ関数boost::unique_を手動で呼び出す必要があることを示します.lock ul(Lockable &m,boost::try_to_lock);//try_を明示して呼び出すlock boost::unique_lock ul(TimedLockable &m,boost::chrono::XXX(n));//try_を明示して呼び出すlock_for
  • しんごうりょう
    信号量はマルチスレッドの同期に使用されます.例えば、生産消費類の問題では、消費者が1つのデータを処理するたびに、データがない場合は待機状態に入り、生産者が1つのデータを生産するたびに、消費者を呼び覚ます.
    <!-- lang: cpp -->
    boost::condition_variable cond;
    boost::mutex mut;
    bool data_ready;
    void wait_for_data_to_process()
    {
        boost::unique_lock<boost::mutex> lock(mut); //      lock_guard
        while(!data_ready)
        {
            cond.wait(lock);  // cond.wait(lock)    mux.unlock(),            cond.notify_XXX() , mut.lock(),     lock_guard(lock_guard                )
        }
        process_data();
    }
    void prepare_data_for_processing()
    {
        retrieve_data();
        prepare_data();
        {
            boost::lock_guard<boost::mutex> lock(mut); //        mut.lock()
            data_ready=true;
        } //            lock,         mut.unlock()
        cond.notify_one();
    }
    
    一度だけ実行する処理
    <!-- lang: cpp -->
    boost::once_flag once;
    void once_func();
    void test()
    {
        boost::call_once(once,once_func); //         ,             ,             ,             (    ),                 ,                。
    }