うーん、不器用なアプローチでできると思います...
「バリア」をソケットでリッスンする独自のプロセスにします。barrier_wait を次のように実装します。
open connection to barrier process
send message telling barrier process I am waiting
block in read() waiting for reply
N 個のスレッドが待機すると、バリア プロセスはそれらすべてに続行するように指示します。次に、各ウェイターはバリア プロセスへの接続を閉じて続行します。
barrier_destroy を次のように実装します。
open connection to barrier process
send message telling barrier process to go away
close connection
すべての接続が閉じられ、バリア プロセスが終了するように指示されると、終了します。
[編集: 確かに、これは待機操作と解放操作の一部としてソケットを割り当てて破棄します。しかし、そうしなくても同じプロトコルを実装できると思います。下記参照。]
最初の質問: このプロトコルは実際に機能しますか? あると思いますが、要件を理解していない可能性があります。
2 番目の質問: 機能する場合、余分なプロセスのオーバーヘッドなしでシミュレートできますか?
答えは「イエス」だと思います。適切なタイミングで、各スレッドがバリア プロセスの「役割を担う」ことができます。現在バリアプロセスの「役割を担っている」スレッドが保持するマスターミューテックスが必要です。詳細、詳細... わかりましたので、barrier_wait は次のようになります。
lock(master_mutex);
++waiter_count;
if (waiter_count < N)
cond_wait(master_condition_variable, master_mutex);
else
cond_broadcast(master_condition_variable);
--waiter_count;
bool do_release = time_to_die && waiter_count == 0;
unlock(master_mutex);
if (do_release)
release_resources();
ここで、(master_mutex
ミューテックス)、master_condition_variable
(条件変数)、waiter_count
(符号なし整数)、N
(別の符号なし整数)、およびtime_to_die
(ブール値) はすべて、barrier_init によって割り当てられ、初期化される共有状態です。 waiter_count
ゼロ、time_to_die
false、およびN
バリアが待機しているスレッド数に初期化されます。
その場合、barrier_destroy は次のようになります。
lock(master_mutex);
time_to_die = true;
bool do_release = waiter_count == 0;
unlock(master_mutex);
if (do_release)
release_resources();
信号処理などの詳細については不明ですが、「最後の 1 つはライトをオフにする」という基本的な考え方は実行可能だと思います。