好吧,我想我可以用笨拙的方法来做到这一点......
让“障碍”成为它自己在套接字上侦听的进程。将 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
一旦所有连接都关闭并且屏障进程被告知离开,它就会退出。
[编辑:当然,这会分配和销毁套接字作为等待和释放操作的一部分。但我认为你可以不这样做就实现相同的协议;见下文。]
第一个问题:这个协议真的有效吗?我认为确实如此,但也许我不了解要求。
第二个问题:如果它确实有效,是否可以在没有额外过程开销的情况下进行模拟?
我相信答案是“是”。您可以让每个线程在适当的时候“扮演”屏障进程的角色。您只需要一个主互斥锁,由当前正在“扮演”屏障进程的任何线程持有。细节,细节......好的,所以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
假和N
屏障正在等待的线程数。
然后 barrier_destroy 将是:
lock(master_mutex);
time_to_die = true;
bool do_release = waiter_count == 0;
unlock(master_mutex);
if (do_release)
release_resources();
不确定有关信号处理等的所有细节......但我认为“最后一个关灯”的基本想法是可行的。