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

C 語言進階:從共享內存到 Memcached 外部緩存實戰

     編輯:關於C語言

C 語言進階:從共享內存到 Memcached 外部緩存實戰

第一部分:System V 共享內存

核心 API 流程

  1. shmget(key, size, flags):創建/獲取共享內存段,返回標識符 shmid。
  2. shmat(shmid, NULL, 0):將共享內存映射到進程地址空間,返回指針。
  3. 讀寫內存(如普通指針)。
  4. shmdt(ptr):解除映射。
  5. shmctl(shmid, IPC_RMID, NULL):刪除共享內存段(引用計數歸零後真正釋放)。

服務端寫入示例

#define SHM_KEY 0x12321
int shmid = shmget(SHM_KEY, BUFSIZ+1, 0764 | IPC_CREAT);
char *shm = shmat(shmid, NULL, 0);
// 寫入數據...
shmdt(shm);
// shmctl(shmid, IPC_RMID, NULL); // 可選:讀端負責刪除
system("ipcs -m"); // 查看狀態

客戶端讀取示例

int shmid = shmget(SHM_KEY, BUFSIZ+1, IPC_CREAT);
char *shm = shmat(shmid, NULL, 0);
puts(shm);
shmdt(shm);
shmctl(shmid, IPC_RMID); // 讀完刪除
system("ipcs -m");

權限掩碼 0764 解析

  • 八進制,三位分別對應 Owner/Group/Other。
  • 7 = 4(r) + 2(w) + 1(x);6 = 4+2;4 = 4(r)。
  • 本例:創建者讀寫執行,同組讀寫,其他唯讀。

關鍵限制

  • 僅限**同一台機器**進程間通信。
  • 生命週期隨內核,需手動清理否則殘留。
  • 無網絡透明性,不適合分布式場景。

第二部分:Memcached 分布式緩存

安裝與驗證

sudo apt-get install memcached
ps -ef | grep memcached  # 確認服務運行

Telnet 手工測試協議

telnet localhost 11211
set id 0 0 5
nihao
STORED
get id
VALUE id 0 5
nihao
END
  • set key flags exptime bytes:存儲。flags 自定義,exptime 過期秒數(0=永不過期),bytes 值長度。
  • get key:獲取。
  • add:僅 key 不存在時存儲(原子性)。

C 客戶端開發:libmemcached

#include 

memcached_st *memc = memcached_create(NULL);
memcached_server_st *servers = memcached_server_list_append(NULL, "127.0.0.1", 11211, &rc);
memcached_server_push(memc, servers);
memcached_server_list_free(servers);

// 存儲
memcached_set(memc, "hello", 5, "world", 5, 0, 0);

// 獲取
size_t vlen; uint32_t flags; memcached_return rc;
char *val = memcached_get(memc, "hello", 5, &vlen, &flags, &rc);

// 刪除
memcached_delete(memc, "hello", 5, 0);

memcached_free(memc);

編譯鏈接

gcc -o demo demo.c -lmemcached
# 需配置 LD_LIBRARY_PATH 包含 /usr/local/lib

第三部分:基於 Memcached 實現分布式鎖(時間鎖)

核心思想

利用 add 原子性:只有 key 不存在時才存儲成功。設置過期時間 expir,自動釋放鎖,避免死鎖。

代碼實現

#include 
#include 

int main() {
    memcached_st *memc = memcached_create(NULL);
    memcached_server_st *servers = memcached_server_list_append(NULL, "127.0.0.1", 11211, &rc);
    memcached_server_push(memc, servers);
    memcached_server_list_free(servers);

    const char *lock_key = "__mem_key_lock";
    time_t expir = 10; // 10 秒自動過期

    // 嘗試獲取鎖
    memcached_return rc = memcached_add(memc, lock_key, strlen(lock_key), "0", 1, expir, 0);
    if (rc != MEMCACHED_SUCCESS) {
        fprintf(stderr, "Lock contention: %s\n", memcached_strerror(memc, rc));
        memcached_free(memc);
        return 1;
    }
    printf("Lock acquired, holding for %ld seconds...\n", expir);
    sleep(expir); // 模擬業務處理

    memcached_free(memc);
    return 0;
}

驗證並發

  • 終端 1 運行程序,輸出 Lock acquired...,休眠 10s。
  • 終端 2 同期間運行,輸出 Lock contention: MEMCACHED_NOTSTORED,獲取失敗。
  • 10s 後鎖自動釋放,終端 2 再次嘗試可成功。

總結對比

特性System V 共享內存Memcached
部署範圍單機分布式集群
數據持久性內存級,掉電丟失內存級,可配置持久化
並發控制需自行加鎖原子操作
語言中立C/C++ 為主多語言客戶端
適用場景高性能本地 IPC分布式緩存、會話、鎖、限流

避坑指南

  • 共享內存:ftok 生成 key 避免衝突;shmctl(IPC_RMID) 及時清理;注意結構體對齊導致的大小差異。
  • Memcached:libmemcached 版本兼容性;設置 LD_LIBRARY_PATH;key 設計加項目前綴防衝突;大值對象序列化開銷;監控 evictions 指標防內存淘汰。
  • 分布式鎖:業務執行時間可能超過鎖過期時間 → 需續租機制;單點 Memcached 故障導致鎖失效 → 生產環境需集群/哨兵模式(或改用 Redis Redlock)。

結語

從單機共享內存到分布式 Memcached,體現了「本地高性能」到「分布式擴展」的架構演進。根據業務規模、一致性要求、運維能力選擇合適方案:**單機高頻 IPC 用共享內存,分布式緩存/鎖/會話用 Memcached/Redis**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved