以下是一个简单的示例代码,实现了一个无锁队列,支持多生产者多消费者:

#include <stdio.h>
#include <stdlib.h>
#include <stdatomic.h>
#include <pthread.h>

#define QUEUE_SIZE 100

typedef struct {
    void* data[QUEUE_SIZE];
    atomic_int head;
    atomic_int tail;
} queue_t;

void queue_init(queue_t* q) {
    q->head = 0;
    q->tail = 0;
}

int queue_push(queue_t* q, void* data) {
    int tail = atomic_load_explicit(&q->tail, memory_order_relaxed);
    int next_tail = (tail + 1) % QUEUE_SIZE;
    if (next_tail == atomic_load_explicit(&q->head, memory_order_acquire)) {
        return 0; // queue is full
    }
    q->data[tail] = data;
    atomic_store_explicit(&q->tail, next_tail, memory_order_release);
    return 1;
}

void* queue_pop(queue_t* q) {
    int head = atomic_load_explicit(&q->head, memory_order_relaxed);
    if (head == atomic_load_explicit(&q->tail, memory_order_acquire)) {
        return NULL; // queue is empty
    }
    void* data = q->data[head];
    atomic_store_explicit(&q->head, (head + 1) % QUEUE_SIZE, memory_order_release);
    return data;
}

queue_t q;
pthread_t producers[10];
pthread_t consumers[10];

void* producer(void* arg) {
    int id = (int)arg;
    for (int i = 0; i < 1000; i++) {
        char* data = malloc(16);
        sprintf(data, "producer %d %d", id, i);
        while (!queue_push(&q, data)) {
            // retry if queue is full
        }
    }
    return NULL;
}

void* consumer(void* arg) {
    int id = (int)arg;
    int count = 0;
    while (count < 1000) {
        char* data = queue_pop(&q);
        if (data != NULL) {
            printf("consumer %d got %s\n", id, data);
            free(data);
            count++;
        }
    }
    return NULL;
}

int main() {
    queue_init(&q);
    for (int i = 0; i < 10; i++) {
        pthread_create(&producers[i], NULL, producer, (void*)i);
        pthread_create(&consumers[i], NULL, consumer, (void*)i);
    }
    for (int i = 0; i < 10; i++) {
        pthread_join(producers[i], NULL);
        pthread_join(consumers[i], NULL);
    }
    return 0;
}

该代码使用了 C11 引入的原子操作来实现无锁队列。queue_pushqueue_pop 分别使用了 memory_order_acquirememory_order_release 来保证正确的内存序。多个生产者和消费者线程使用了同一个队列,并且在队列满或空时使用了自旋等待来避免竞争。这种实现方式虽然没有使用锁来保证线程安全,但仍然存在 ABA 问题和内存泄漏问题,需要进一步优化和完善

linux 内核 c语言程序 实现 多生产者 多消费者 不使用原子变量 无锁 队列。请提供实现示例代码。

原文地址: https://www.cveoy.top/t/topic/e8uV 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录