Top/Lang/C++/C++11/thread

目次

初めに

std::thread

thread の作成

引数付き関数を別 thread で実行する

クラスメンバ関数をスレッド関数にする場合

thread 終了を待機する

thread 終了を待機可能かどうか判定する

thread を手放す

thread の識別

現在の thread の処理を明け渡す

void std::this_thread::yield() noexcept;

現在の thread をスリープする

namespace std {
    namespace this_thread {
        template <class Clock, class Duration>
        void sleep_until( const chrono::time_point<Clock, Duration>& abs_time);
        template <class Rep, class Period>
        void sleep_for(const chrono::duration<Rep, Period>& rel_time);
    }
}

並行実行できる thread の数を取得する

namespace std {
    class thread {
      public:
        static unsigned int hardware_concurrency() noexcept;
    };
}

mutex

namespace std {
    class mutex {
      public:
        void lock();
        bool try_lock();
        void unlock();
    };

    class recursive_mutex {
      public:
        void lock();
        bool try_lock();
        void unlock();
    };
}

std::mutex

std::recursive_mutex

std::timed_mutex

std::timed_recursive_mutex

std::shared_mutex [C++17]

std::shared_timed_mutex [C++14]

リソースのロックを管理する

std::lock_guard

#include <mutex>
{
    std::mutex mtx;
    {
         std::lock_guard<mutex> lk( mtx );  // ここからロックが掛かる
         // 処理...

    }  // lk の有効なスコープを抜け、lk のインスタンスが消滅すると同時にロック解除となる
}

std::unique_lock

複数のリソースをロックする

ロックせずに排他アクセスする

std::memory_order

std::atomic

スレッドセーフに1度だけ関数を呼び出す

条件変数を使用する

thread をまたいで値や例外を受け渡す

使い方

  1. std::promise の実体生成し下記を呼び、その実体に対応する std::future の実体を取得する。
    get_future()
  2. 値と例外は、以下のいずれかを用いてどちらか一つを、1回だけ設定出来る。
    set_value()
    set_exception()
    • 値または例外が既に設定された状態で再度これらが呼び出された場合、 std::future_error 例外が送出される。
    • 対応する std::future が値や例外を受け取るタイミングを、このスレッドの終了時まで送らせたい場合は、以下のいずれかを使う
      set_value_at_thread_exit()
      set_exception_at_thread_exit()
  3. std::promise の get_future() で取得した std::future の get() 関数を使い、std::promise で設定された値を受け取る。
    • 設定されたのが値ではなく例外だった場合は、例外が送出される。
    • まだ std::promise で値も例外も設定されていなかった場合、内部で wait() を呼び出す。
      • wait() は、値または例外の設定を待機するもので、設定されるまでは呼び出し元のスレッドをブロックする。
    • 値の設定待ちに条件を付けたい場合は、以下を使用する
      wait_for(   std::chrono::duration   d  )  // 指定した時間 d  だけ待機する
      wait_until( std::chrono::time_point tp )  // 指定した時刻 tp まで待機する
      これらの返り値は以下
      std:future_status::ready     // 指定時間内に値か例外が設定された
      std:future_status::timeout   // 値も例外も設定されないまま指定時間を過ぎた
      std:future_status::deferred  // 実行のタイミングが延期されている

使い方の例

#include <iostream>
#include <thread>
#include<future>

static std::mutex g_print_mutex;
void LockPrintf( const std::string & str )
{
  std::lock_guard<std::mutex>	lk( g_print_mutex );
  std::cout << str << std::endl;
}

void ThreadFuncA( std::promise<std::string> pr )
{
  std::string sendstr ="from ThreadFuncA";
  pr.set_value( sendstr );       // 他のスレッドに受け渡す値を設定
  LockPrintf(  "ThreadFuncA" );
}

int main( int argc, char * argv[] )
{
  std::promise<std::string> prom;
  std::future<std::string>  futu = prom.get_future();  // promise で他スレッドで設定された値を取得

  std::thread th_a( ThreadFuncA, move( prom ) );

  std::string future_string = "Rcv from A: " + futu.get();
  LockPrintf( future_string );

  th_a.join();
  return( 0 );
}

非同期処理をする

スレッドローカル変数を使用する


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2023-03-19 (日) 22:06:49