Linux 核心訊息佇列使用的 struct msgbuf 定義:
struct msgbuf {
long mtype; // 訊息類型
char mtext[1]; // 柔性陣列:實際長度由 malloc 決定
};
關鍵點:mtext[1] 只有 1 字元,但透過 malloc(sizeof(struct msgbuf) + extra_len) 分配額外空間,即可存放任意長度訊息。這是 C99 標準化前的經典「柔性陣列」寫法(C99 可寫 char mtext[];)。
msgsnd.c#define _GNU_SOURCE #include#include #include #include #include #include #define QUE_ID 2 int main(void) { int qid = msgget(QUE_ID, IPC_CREAT | 0600); if (qid == -1) { perror("msgget"); exit(1); } printf("Queue %d created\n", qid); // 分配結構體 + 100 字節訊息空間 struct msgbuf *msg = malloc(sizeof(struct msgbuf) + 100); msg->mtype = 1; strcpy(msg->mtext, "deepfuture.iteye.com"); // 發送:最後參數 0 表阻塞等待 if (msgsnd(qid, msg, 100, 0) == -1) { perror("msgsnd"); exit(1); } printf("Message sent\n"); free(msg); return 0; }
msgrcv.c#define _GNU_SOURCE #include#include #include #include #include #define QUE_ID 2 int main(void) { int qid = msgget(QUE_ID, 0); // 不建立,只取得 if (qid == -1) { perror("msgget"); exit(1); } struct msgbuf *msg = malloc(sizeof(struct msgbuf) + 100); // 接收類型 0 表任意類型,IPC_NOWAIT 非阻塞 if (msgrcv(qid, msg, 101, 0, 0) == -1) { perror("msgrcv"); exit(1); } printf("Received: %s\n", msg->mtext); free(msg); return 0; }
gcc msgsnd.c -o msgsnd gcc msgrcv.c -o msgrcv ./msgsnd # 先執行發送 ./msgrcv # 再執行接收,輸出 "deepfuture.iteye.com"
struct msgbuf (malloc 區塊) +----------------+------------------+ | long mtype (8B)| char mtext[100] | <- 實際可用 100 字節 +----------------+------------------+ ^ ^ msg msg->mtext
typedef struct {
uint32_t len; // 資料長度
uint8_t data[]; // C99 柔性陣列
} buffer_t;
// 分配 1KB 緩衝區
buffer_t *buf = malloc(sizeof(buffer_t) + 1024);
buf->len = 1024;
// 直接操作 buf->data[0...1023]
此模式廣泛用於網路封包、驅動程式 DMA 緩衝區、共享記憶體等場景。