【问题标题】:Reusable Barrier Algorithm可重用的屏障算法
【发布时间】:2011-06-30 06:36:47
【问题描述】:

我正在研究“信号量小书”一书中的可重用屏障算法(存档here)。

谜题在第 31 页(基本同步模式/可重用障碍),我想出了一个与书中的解决方案(两阶段障碍)不同的“解决方案”(或没有)。

这是每个线程的“代码”:

# n = 4; threads running
# semaphore = n max., initialized to 0
# mutex, unowned.

start:
    mutex.wait()
        counter = counter + 1
        if counter = n:
            semaphore.signal(4) # add 4 at once
            counter = 0
    mutex.release()
    semaphore.wait()
        # critical section
    semaphore.release()
goto start

这似乎确实有效,我什至在线程的不同部分插入了不同的睡眠计时器,它们仍然等待所有线程都来,然后再继续每个循环。我错过了什么吗?有没有条件会失败?

我已经使用 Windows 库 SemaphoreMutex 函数实现了这一点。

更新:

感谢 starblue 提供answer。事实证明,如果由于某种原因线程在mutex.release()semaphore.wait() 之间变慢,则在完整循环后到达semaphore.wait() 的任何线程都将能够再次通过,因为将有一个@987654332 @ 未使用的信号。

并为线程号 3 设置了Sleep 命令,我得到了this 结果,其中可以看到线程 3 第一次错过了一圈,而线程 1 已经完成了 2 圈,然后赶上了第二回合(实际上是第一回合)。

再次感谢大家的意见。

【问题讨论】:

标签: multithreading algorithm concurrency mutex barrier


【解决方案1】:

一个线程可以通过屏障运行多次,而其他线程则根本不运行。

【讨论】:

  • 其实它不会运行几次。有一个柜台。只有当其中一个线程发现它被设置为N(所有线程都在等待)时,它才会发出信号量(N)的信号,以便它们都可以通过。计数器再次设置为 0,因此屏障被锁定。只有在所有人都在等待时,他们才会全部通过。
  • 所以一个线程不能运行多次,因为一个线程将计数器加1,只加1一次。并在发现计数器等于 N 时将计数器重置为 0(包括自身在内的所有线程都将计数器递增)。一根线从不孤单。信号量将保持锁定状态,直到它们都到达,然后它们就走了。它在等待/锁定时永远无法完成循环。
  • 如果其他线程不经过信号量,那么一个线程可以经过N次。只要信号量打开,计数器就无关紧要。
  • 其他人会在哪里?卡在互斥锁内?然后没有人可以进入互斥锁,他们回到循环的开头,但无法进入;这是一个僵局;如果一个线程卡在某个地方,每个人都会卡在互斥锁或信号量上。仍然试图解决这个问题。感谢您的意见。
  • 不,它们会在互斥体之后但在信号量之前。在执行semaphore.signal(4) 后它们不会被阻止,它们只是没有特殊原因不会运行。
猜你喜欢
  • 2013-10-20
  • 2018-05-11
  • 2014-08-04
  • 2014-12-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-31
  • 1970-01-01
  • 2021-10-10
相关资源
最近更新 更多