需要混合信号量/循环屏障

时间:2013-07-25 04:52:18

标签: multithreading concurrency semaphore cyclicbarrier

我正在开发一个分阶段的工作系统,目前的工作原理如下(伪代码):

cyclicbarrier.init(numthreads)
on each thread:
  for each stage s:
    loop forever:
      pop job from joblist[s]
      if no job:
        break
      execute job
    wait at cyclicbarrier

这会导致舞台中的所有作业在进入下一阶段之前完成执行。

cyclicbarrier使用两个信号量实现:

sem1(0)
sem2(0)
n = 0

function wait:
  if atomic_incr(n) == maxthreads:
    sem1.signal(maxthreads)
  sem1.wait()

  if atomic_decr(n) == 0:
    sem2.signal(maxthreads)
  sem2.wait()

我想添加对作业的支持,以便能够将1个或多个作业添加到当前正在运行的阶段,并在阶段继续之前执行这些作业。上面的代码会执行此操作,但是如果在线程到达屏障后添加此作业,那么它将以次优的方式执行,因为等待的线程可以执行它但不是。

我已经将问题归结为需要一种混合semaphore / cyclicbarrier,为方便起见,我会称之为sembarrier。以下是它的运作方式:

function wait:
  n--
  if n < 0 and n > -maxthreads:
    suspend until signaled
  else if n <= -maxthreads:
    signal(maxthreads)

基本上,这个sembarrier就像semaphore一样,但是当有足够的线程在等待它时,它的行为类似于cyclicbarrier并将它们全部释放。

所以,这是使用sembarrier的新实现。

sembarrier构造函数如下所示:

sembarrier(initial_value, num_threads)

为每个阶段创建sembarrier

n = num_theads
for each stage s:
  sembarrier[s].init(0, n)

这将是修改后的循环,使用sembarrier数组:

on each thread:
  for each stage s:
    loop forever:
      sembarrier[s].wait()
      pop job from joblist[s]
      if no job:
        break;
      execute job

此外,添加到joblist时:

function AddJob(stage s, job j):
  joblist[s].push(j)
  sembarrier[s].signal()

问题:

1)我如何有效地实施sembarrier?我可以访问基本的并发结构,例如互斥锁和信号量。我也有标准的原子操作。

2)我的原始问题是否有另一种解决方案?

谢谢!

0 个答案:

没有答案