轻量级多读取器/单写入器队列实现

时间:2016-04-13 12:22:53

标签: multithreading synchronization message-queue lock-free

对于小型线程池(等于物理内核的数量),我需要一个非常简单的多读取器/单写入器队列实现。现在我用条件变量实现了它,但是我正在为未来的版本探索更轻的替代品。我结束了这样的事情(C伪代码):

#define QUEUE_MAXSIZE 16

struct queue {
  OS_WAIT_OBJECT writer_waitobj;
  OS_WAIT_OBJECT reader_waitobj;
  size_t head;
  size_t tail;
  int data[QUEUE_MAXSIZE];
};

/* Called by a single writer. */
void enqueue(struct queue* queue, int value)
{
  /* If queue is full wait to avoid overwriting. */
  while (queue->head - queue->tail == QUEUE_MAXSIZE) {
    OS_WAIT(queue->writer_waitobj);
  }

  /* There are a single writer so synchronization isn't necessary. */
  queue->data[queue->head] = value;
  queue->head++;

  /* If queue was empty, signal the new state to one reader. */
  if (queue->head == queue->tail) {
    OS_AWAKE_ONE(queue->reader_waitobj);
  }
}

/* Called by (few) multiple readers. */
int dequeue(struct queue* queue)
{
  int value;
  const size_t my_tail = tail;

  /* If queue is empty readers must wait. */
  while (queue->head == my_tail) {
    OS_WAIT(queue->reader_waitobj)
  }

  /* Spin-lock readers synchronization. */
  do {
    value = queue->data[my_tail];
  } while (!CPU_COMPARE_AND_SWAP(queue->tail, my_tail, my_tail+1));

  /* If queue was full, signal the new state to writer. */
  if (queue->head - my_tail == QUEUE_MAXSIZE) {
    OS_AWAKE_ONE(queue->writer_waitobj);
  }

  return value;
}

此实施是否正确?故障在哪里?什么轻量级等待信号/唤醒信号设施提供主操作系统(Linux,BSD,OS X,Windows)?

修改

OS_WAIT_OBJECT不会被强制为条件变量。这是一个简单的“睡觉,直到调度程序唤醒你,因为其他人发送了信号”。

0 个答案:

没有答案