下周我们正在为我们的考试而学习,并且我们的老师已经进行了练习,我们只是看不到解决方案:
如何同步n
个线程,以便所有n
个线程在特定位置等待,并且只有当所有n
个线程都到达该位置时才继续“工作”? / p>
我们被允许使用Mutex和Semaphore结构。解决方案应该很简单,但我们无法找到答案。
答案 0 :(得分:0)
这里有一个很大的暗示。你需要2个信号量,都有N
个标志。您可以使用额外的线程解决此问题。关键是你可以多次在信号量上调用down()
。例如如果您在信号量上拨打down()
8次,则需要全部8 up()
秒才能继续。
// an additional thread (not one of the N)
void trigger(Semaphore* workersCollect, Semaphore* workersRelease, int n)
{
while(true)
{
for (int i = 0; i < n; ++i)
workersCollect->down();
for (int i = 0; i < n; ++i)
workersRelease->up();
}
}
// Prototype for the "checkpoint" function (exercise for the reader)
void await(Semaphore* workersCollect, Semaphore* workersRelease);
通过使用更复杂的状态检查,您也可以在没有额外线程的情况下解决它。
这种设计有一个缺点。如果一个工人非常快地完成它的工作,它可以抓住多个任务(而另一个线程最终根本没有运行)。如果你有一个线程池设计,这很好,但是如果每个线程都应该在它自己的数据集的不同部分上工作,那就太糟糕了。
要解决这个问题,每个线程需要一个信号量。类似于
的东西Semaphore workerRelease[N];
但要小心避免错误分享。 (您不希望缓存行上有超过1个信号量。)