仅使用C ++中的信号量和/或互斥量同步n个线程

时间:2018-01-30 19:23:11

标签: c++ multithreading mutex semaphore synchronize

下周我们正在为我们的考试而学习,并且我们的老师已经进行了练习,我们只是看不到解决方案:

如何同步n个线程,以便所有n个线程在特定位置等待,并且只有当所有n个线程都到达该位置时才继续“工作”? / p>

我们被允许使用Mutex和Semaphore结构。解决方案应该很简单,但我们无法找到答案。

1 个答案:

答案 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个信号量。)