C++ には std::condition_variable に notify_all_at_thread_exit() もある2020年10月07日 12時25分36秒

condition_variable に notify_all は待機している全てのスレッドを起こす。そして、変化球版に notify_all_at_thread_exit() がある。

こちらの例も、十個のスレッドを生成し condition_variable を用いて待機。メインスレッドではスレッドの終了がうまく処理できなくなるので、notify_all_at_thread_exit() を呼ぶためのスレッドを生成し、一気に全てのスレッドを起こす。

% cat condition_variable.cpp
#include <thread>
#include <condition_variable>
#include <chrono>
#include <iostream>

std::mutex m;
std::condition_variable cv;

void print( int n )
{
    std::unique_lock< std::mutex > lock( m );
    std::cout << "THREAD in  " << n << std::endl;
    cv.wait(lock);
    std::cout << "THREAD out " << n << std::endl;
}

int main()
{
    std::thread threads[ 10 ];
    for( int i = 0; i < 10; ++i )
        threads[ i ] = std::thread( print, i );

    std::this_thread::sleep_for( std::chrono::seconds( 1 ) );

    std::thread([ & ]
    {
        std::unique_lock< std::mutex > lock( m );
        std::cout << "notify_all_at_thread_exit()" << std::endl;
        std::notify_all_at_thread_exit( cv, std::move( lock ) );
    }).detach();

    for( auto& t: threads )
        t.join();

    std::cout << "DONE" << std::endl;
}

コンパイルして実行した結果。スレッドライブラリを使うので -lptherad が必要になる。

% c++ -std=c++11 condition_variable.cpp -lpthread
% ./a.out
THREAD in  1
THREAD in  2
THREAD in  3
THREAD in  4
THREAD in  0
THREAD in  5
THREAD in  6
THREAD in  7
THREAD in  8
THREAD in  9
notify_all_at_thread_exit()
THREAD out 9
THREAD out 7
THREAD out 5
THREAD out 0
THREAD out 3
THREAD out 1
THREAD out 4
THREAD out 2
THREAD out 8
THREAD out 6
DONE
なお、実行結果はプログラムを走らせる度に変わる。

前回次回