Linux 提供豐富的 IPC 機制。本筆記整理管道、FIFO、訊息佇列、信號量、共享記憶體、mmap、檔案鎖、終端控制、高級 I/O 多路轉接等核心 API 簽名、參數說明、返回值與常見用法,適合系統程式開發者隨時查閱。
#include <unistd.h> int pipe(int fd[2]); // fd[0]讀, fd[1]寫,單向、容量有限 FILE *popen(const char *cmd, const char *mode); // 建立子進程執行 shell 命令並建管道 int pclose(FILE *stream); // 關閉 popen 管道,返回子進程狀態 #include <sys/stat.h> int mkfifo(const char *path, mode_t mode); // 建立命名管道 (FIFO),供無親緣進程通訊
ftok 產生 key)#include <sys/ipc.h> key_t ftok(const char *path, int proj); // 產生唯一 IPC key // 訊息佇列 #include <sys/msg.h> int msgget(key_t key, int flag); // 取得/建立佇列 ID int msgsnd(int msqid, const void *ptr, size_t len, int flag); // 發送 ssize_t msgrcv(int msqid, void *ptr, size_t max, long type, int flag); // 接收 int msgctl(int msqid, int cmd, struct msqid_ds *buf); // 控制 // 信號量 #include <sys/sem.h> int semget(key_t key, int nsems, int flag); // 取得信號量集 ID int semctl(int semid, int semnum, int cmd, ...); // 設定/查詢 int semop(int semid, struct sembuf *ops, unsigned n); // 原子操作 (P/V) // 共享記憶體 #include <sys/shm.h> int shmget(key_t key, size_t size, int flag); // 取得共享記憶體 ID void *shmat(int shmid, const void *addr, int flag); // 映射到位址空間 int shmdt(const void *addr); // 解除映射 int shmctl(int shmid, int cmd, struct shmid_ds *buf); // 控制
#include <sys/mman.h> void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off); // 建立映射 int munmap(void *addr, size_t len); // 解除映射 #include <fcntl.h> int shm_open(const char *name, int oflag, mode_t mode); // 開啟/建立共享記憶體物件 int shm_unlink(const char *name); // 移除物件
#include <sys/file.h> int flock(int fd, int op); // LOCK_SH(共享), LOCK_EX(獨佔), LOCK_UN(解鎖), LOCK_NB(非阻塞)
#include <termios.h> int tcgetattr(int fd, struct termios *t); // 取得屬性 int tcsetattr(int fd, int act, const struct termios *t); // 設定屬性 speed_t cfgetispeed/ospeed(const struct termios *t); // 取得波特率 int cfsetispeed/ospeed(struct termios *t, speed_t s); // 設定波特率 int tcsendbreak, tcdrain, tcflush, tcflow; // 行控制 int isatty(int fd); // 判斷是否終端 char *ttyname(int fd); // 取得終端名稱 // 偽終端 int posix_openpt(int flags); int grantpt, unlockpt; char *ptsname(int fd);
// select
#include <sys/select.h>
int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv);
FD_ZERO/SET/CLR/ISSET(fd, &set); // 描述符集合操作
// poll
#include <poll.h>
int poll(struct pollfd fds[], nfds_t nfds, int timeout);
// fds[i]: {fd, events, revents} 更簡潔,無 FD_SETSIZE 限制
// 缺點:每次調用需遍歷全集合、重複複製用戶/核心態、返回後仍需輪詢就緒 fd
// 現代替代:epoll (Linux)、kqueue (BSD)、IOCP (Windows)
掌握 IPC 全景,能根據效能、可移植性、程式複雜度選擇最適合的進程通訊方式。