C中的非繁忙阻塞队列实现

我试图在C中实现一个队列,导致进程非忙等待,直到队列中有一个元素要消耗。 我尝试过两种不同的尝试来实现这一目标。

我遇到的第一个问题是,如果enqueue / dequeue操作有条件检查边界( if (q-> count == QUEUESIZE)),对sem_wait的调用将立即返回,因为没有其他进程获得锁定。

如果我将条件更改为while (q-> count == QUEUESIZE),我相信消费者进程将“忙等待”,直到生产者进程发布信号量,这不是我实现的目标,并通过测试,我发现消费者进程不会获得锁定并继续。

我认为我很接近,但我似乎无法弄清楚如何解决这些问题。 我考虑过添加条件变量或pthread_mutex,但是在添加额外的复杂性之前想要耗尽信号量选项。

#define QUEUESIZE 48 typedef struct { char q[QUEUESIZE+1][150]; int first; int last; int count; sem_t *lock; } Queue; init_queue(Queue *q, sem_t *l) { q->first = 0; q->last = QUEUESIZE-1; q->count = 0; q->lock = l; } enqueue(Queue *q, char x[150]) { while(q->count == QUEUESIZE) sem_wait(q->lock); if (q->count == 0) { if (sem_post(q->lock) == -1) { printf("Thread failed to unlock semaphore\n"); } } q->last = (q->last+1) % QUEUESIZE; strcpy(q->q[ q->last ],x); q->count = q->count + 1; } dequeue(Queue *q,char *ptr) { char x[150]; while(q->count == 0) sem_wait(q->lock); if (q->count == QUEUESIZE) { if (sem_post(q->lock) == -1) { printf("Thread failed to unlock semaphore\n"); } } strcpy(ptr,q->q[ q->first]); q->first = (q->first+1) % QUEUESIZE; q->count = q->count - 1; } 

根据要求,这是我的解决方案。

 #define QUEUESIZE 50 typedef struct { char q[QUEUESIZE][150]; int first; int last; int count; sem_t *full; sem_t *empty; sem_t *excl; } Queue; void init_queue(Queue *q, sem_t *f,sem_t *e, sem_t *ee,) { q->first = 0; q->last = QUEUESIZE-1; q->count = 0; q->full = f; q->empty = e; q->excl = ee; } void enqueue(Queue *q, char x[150]) { sem_wait(q->empty); sem_wait(q->excl); q->last = (q->last+1) % QUEUESIZE; strcpy(q->q[ q->last ],x); q->count = q->count + 1; sem_post(q->excl); sem_post(q->full); } void dequeue(Queue *q,char *ptr) { sem_wait(q->full); sem_wait(q->excl); strcpy(ptr,q->q[ q->first]); q->first = (q->first+1) % QUEUESIZE; q->count = q->count - 1; sem_post(q->excl); sem_post(q->empty); } 

我初始化信号量如下:

 sem_init(full,1,0); sem_init(empty,1,49); sem_init(dequeue_excl,1,1); sem_init(enqueue_excl,1,1);