关键词:IPC、信号、管道、FIFO、消息队列、信号量、共享内存、套接字、内核对象、同步机制
在 Linux 系统中,进程是资源隔离的基本单位,彼此间通常无法直接访问彼此的地址空间。因此需要一套机制,使得多个进程之间可以:
这些功能由 Linux IPC(Inter-Process Communication)子系统实现。
类型 | 描述 |
---|---|
信号 | 最基本的异步通知机制 |
管道/FIFO | 字节流通信机制,面向数据流 |
消息队列 | 面向结构化消息,先进先出 |
信号量 | 同步与互斥,典型用于资源控制 |
共享内存 | 多进程映射同一段内存,效率最高 |
套接字 | 网络与本地通信统一抽象,支持多协议 |
信号是进程间最早被引入的通信机制,本质上是一个异步事件通知。
示例信号 | 描述 |
---|---|
SIGINT | 中断(Ctrl+C) |
SIGTERM | 终止进程请求 |
SIGKILL | 无条件终止进程(不可捕获) |
SIGCHLD | 子进程结束通知父进程 |
kill(pid, sig)
:向指定进程或进程组发送信号;signal(sig, handler)
:设置信号处理函数;sigaction()
:更强大的信号控制;sigprocmask()
:阻塞/允许某些信号;sigqueue()
:带参数的信号发送。task_struct
中包含 sigpending
和 signal
字段;do_signal()
派发;SIGKILL
);SIGRTMIN
~ SIGRTMAX
)支持有序队列与附加参数。管道是最基本的 IPC 数据流机制,数据在两个进程间以 FIFO 形式流动。
int pipe(int pipefd[2]); // pipefd[0]=read, pipefd[1]=write
特点:
pipe_inode_info
结构实现;可跨进程、不限于亲缘关系:
mkfifo /tmp/myfifo
特点:
< /tmp/myfifo
、> /tmp/myfifo
。struct pipe_inode_info
管理缓冲区、读写端等。消息队列允许进程以“消息”为单位进行通信,每条消息是结构化数据(类型 + 数据内容)。
int msgget(key_t key, int msgflg);
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
struct msg_queue {
struct list_head q_messages;
...
};
q_messages
;msgmax
)。信号量提供一种同步机制,用于控制多个进程对共享资源的访问,支持阻塞和非阻塞操作。
int semget(key_t key, int nsems, int semflg);
int semop(int semid, struct sembuf *sops, size_t nsops);
semid
索引;semop()
支持加锁/解锁操作(P/V操作);struct sem_array {
struct sem *sem_base;
...
};
多个进程将一段物理内存映射到各自虚拟地址空间,实现高效通信。
int shmget(key_t key, size_t size, int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
特点:
shmid_kernel
描述共享段;类型 | 描述 |
---|---|
UNIX 域套接字 | 仅限本机通信,文件系统路径寻址 |
INET 套接字 | 网络通信,使用 IP 与端口 |
STREAM | 面向连接,类似 TCP |
DGRAM | 无连接,类似 UDP |
int socket(int domain, int type, int protocol);
int bind(int sockfd, struct sockaddr *addr, socklen_t addrlen);
int connect(int sockfd, struct sockaddr *addr, socklen_t addrlen);
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
sock
结构表示;sk_buff
结构管理。Linux 提供 /proc/sysvipc/
系统接口与 ipcs
工具来统一查看 IPC 对象:
ipcs -m # 共享内存
ipcs -q # 消息队列
ipcs -s # 信号量
可以使用 ipcrm
删除对象。
每个 IPC 对象(shm、sem、msg)都可以在命名空间中隔离,容器技术(如 Docker)广泛使用。
unshare --ipc
文件路径 | 作用描述 |
---|---|
kernel/signal.c |
信号实现与分发 |
ipc/msg.c |
消息队列实现 |
ipc/sem.c |
信号量实现 |
ipc/shm.c |
共享内存实现 |
fs/pipe.c |
管道与 FIFO 实现 |
net/unix/af_unix.c |
UNIX 域 socket 实现 |
include/linux/ipc_namespace.h |
IPC 命名空间 |
include/linux/shm.h |
共享内存头文件 |