利用锁和条件变量实现线程安全的阻塞队列
1、阻塞队列定义:
typedef struct data_block{
char* data;
int length;
}data_block_t;
typedef struct block_queue {
data_block_t **blocks;
int head;
int tail;
int capacity;
int count;
pthread_mutex_t lock;
pthread_cond_t not_empty;
pthread_cond_t not_full;
atomic_bool closed;
} block_queue_t;
2、队列管理函数:
block_queue_t* queue_create(int max_size);
void queue_destroy(block_queue_t *queue);
int queue_enqueue(block_queue_t *queue, data_block_t *block);
data_block_t* queue_dequeue(block_queue_t *queue);
bool queue_remove_block(block_queue_t *queue, data_block_t *target_block);
void queue_close(block_queue_t *queue);
void queue_clear(block_queue_t *queue);
具体实现涉及到多线程的一些知识以及pthread库的使用,其实主要就是上锁解锁操作、利用条件变量阻塞线程和唤醒线程。
阻塞队列中的条件变量的作用是:让生产者 / 消费者线程在 "条件不满足时(队列满 / 空)"高效阻塞休眠 (不占 CPU),在 "条件满足时(队列非满 / 非空)"精准被唤醒,而非无意义地轮询检查。
下面列举出队的具体实现:
data_block_t* queue_dequeue_block(block_queue_t *queue) {
if (!queue) {
return NULL;
}
pthread_mutex_lock(&queue->lock);
while (queue->count == 0 && !atomic_load(&queue->closed)) {
pthread_cond_wait(&queue->not_empty, &queue->lock);
}
if (queue->count == 0) {
pthread_mutex_unlock(&queue->lock);
return NULL;
}
data_block_t *block = queue->blocks[queue->head];
queue->blocks[queue->head] = NULL;
queue->head = (queue->head + 1) % queue->capacity;
queue->count--;
// Signal waiting producers
pthread_cond_signal(&queue->not_full);
pthread_mutex_unlock(&queue->lock);
return block;
}