首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

環形佇列(Circular Queue)C語言無鎖實現與生產消費模型

     編輯:關於C

介面設計 fs_loop_queue.h

#ifndef FS_LOOP_QUEUE_H
#define FS_LOOP_QUEUE_H
#include "fs_define.h"

struct fs_loop_queue;
struct fs_loop_queue* fs_create_loop_queue(size_t len);
bool fs_loop_queue_push(struct fs_loop_queue*, void* item);
void* fs_loop_queue_pop(struct fs_loop_queue*);
bool fs_loop_queue_full(struct fs_loop_queue*);
bool fs_loop_queue_empty(struct fs_loop_queue*);
void fs_loop_queue_free(struct fs_loop_queue*);

#endif

實現 fs_loop_queue.c

#include <stdio.h>
#include "fs_loop_queue.h"
#include "fs_malloc.h"

struct fs_loop_queue {
    void **que;           // 元素指標陣列
    size_t head;          // 寫入位置
    size_t tail;          // 讀取位置
    size_t max_len;       // 容量
    unsigned long script_id;  // 業務標識
};

#define _pos_add(x, n, max)  x = (x + n) % max

struct fs_loop_queue* fs_create_loop_queue(size_t len) {
    struct fs_loop_queue *q = fs_malloc(sizeof(*q));
    fs_zero(q, sizeof(*q));
    q->max_len = len;
    q->que = fs_malloc(sizeof(void*) * len);
    fs_zero(q->que, sizeof(void*) * len);
    return q;
}

bool fs_loop_queue_push(struct fs_loop_queue *q, void *item) {
    if (fs_loop_queue_full(q)) return false;
    q->que[q->head] = item;
    _pos_add(q->head, 1, q->max_len);
    return true;
}

void* fs_loop_queue_pop(struct fs_loop_queue *q) {
    if (fs_loop_queue_empty(q)) return NULL;
    void *item = q->que[q->tail];
    q->que[q->tail] = NULL;
    _pos_add(q->tail, 1, q->max_len);
    return item;
}

bool fs_loop_queue_full(struct fs_loop_queue *q) {
    return ((q->head + 1) % q->max_len) == q->tail;
}
bool fs_loop_queue_empty(struct fs_loop_queue *q) {
    return q->head == q->tail;
}
void fs_loop_queue_free(struct fs_loop_queue *q) {
    fs_free(q->que);
    fs_free(q);
}

設計亮點與無鎖特性

  • 單生產單消費無鎖: head 僅生產者寫、tail 僅消費者寫,head==tail 判空、(head+1)%cap==tail 判滿,無競態條件(需記憶體屏障/volatile 保證可見性)。
  • 浪費一格區分滿空: 犧牲 1 個槽位,避免額外計數器與原子操作。
  • 元素型別泛化: void** 陣列存指標,支援任意型別載荷。
  • 自定義記憶體管理: fs_malloc/fs_free/fs_zero 適配專案記憶體池。

使用範例

struct fs_loop_queue *q = fs_create_loop_queue(1024);
// 生產者執行緒
while (running) {
    Task *t = create_task();
    while (!fs_loop_queue_push(q, t)) sched_yield();  // 滿則讓權
}
// 消費者執行緒
while (running) {
    Task *t = fs_loop_queue_pop(q);
    if (t) { process(t); destroy_task(t); }
    else sched_yield();
}

擴展方向

  • 多生產/多消費:需原子操作 __sync_bool_compare_and_swap 或 mutex 保護 head/tail。
  • 批次操作:push_batch/pop_batch 減少函式呼叫開銷。
  • 阻塞版本:結合條件變數/信號量實現 blocking_push/pop。
  • 無鎖 MPMC:參考 LCRQ、Boost lockfree queue 等進階演算法。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved