当前位置:首页 > 系统教程 > 正文

Linux进程间通信(IPC)完全攻略:从管道到System V

在Linux系统中,每个进程都有独立的地址空间,要实现进程间的数据交换,必须使用特定的通信机制,即Linux进程间通信(IPC)。本文将全方位讲解管道(匿名管道、进程池)、命名管道以及System V IPC(共享内存、消息队列、信号量),帮助小白彻底搞懂这些概念与用法。

一、管道通信:最古老的IPC

管道通信是一种半双工的通信方式,数据只能单向流动。它分为匿名管道和命名管道。

1. 匿名管道(Pipe)

匿名管道用于具有亲缘关系的进程之间(如父子进程)。它通过pipe()系统调用创建,返回两个文件描述符:fd[0]用于读,fd[1]用于写。父进程关闭读端,子进程关闭写端,即可实现单向通信。

// 匿名管道示例#include #include int main() {    int fd[2];    pipe(fd);    if (fork() == 0) {        close(fd[1]); // 子进程关闭写端        char buf[128];        read(fd[0], buf, sizeof(buf));        printf("子进程收到:%s", buf);        close(fd[0]);    } else {        close(fd[0]); // 父进程关闭读端        write(fd[1], "Hello, 儿子!", 13);        close(fd[1]);    }    return 0;}    

进程池概念:可以利用管道管理多个工作进程,父进程通过管道分配任务,实现简单的进程池模型。

Linux进程间通信(IPC)完全攻略:从管道到System V Linux进程间通信 管道通信 命名管道 System IPC 第1张

2. 命名管道(FIFO)

命名管道弥补了匿名管道只能用于亲缘进程的缺陷,它通过一个文件名在文件系统中存在,任意两个进程可通过该文件进行通信。使用mkfifo()创建,然后像操作普通文件一样open/read/write

// 创建命名管道mkfifo("myfifo", 0666);// 进程A:写int fd = open("myfifo", O_WRONLY);write(fd, "Hello", 5);// 进程B:读int fd = open("myfifo", O_RDONLY);read(fd, buf, 128);    

注意:命名管道必须同时以适当模式打开,否则会阻塞。

二、System V IPC

System V IPC包括共享内存、消息队列和信号量,它们使用相同的授权系统和标识符(key)。

1. 共享内存

共享内存是最快的IPC形式,它允许多个进程直接访问同一块内存区域,避免了数据拷贝。使用shmget()创建,shmat()映射,shmdt()分离。

key_t key = ftok("shmfile",65);int shmid = shmget(key,1024,0666|IPC_CREAT);char str = (char) shmat(shmid,(void*)0,0);// 进程间通过str读写shmdt(str);    

2. 消息队列

消息队列是消息的链表,允许一个或多个进程写入或读取消息。避免了管道的数据无边界问题。使用msgget()msgsnd()msgrcv()

3. 信号量

信号量用于进程同步,控制多个进程对共享资源的访问。通常与共享内存配合使用。

三、总结

本文详细介绍了Linux进程间通信的三大类:管道(匿名、命名)和System V IPC。管道适合简单流式数据,命名管道突破了亲缘限制,而System V IPC提供了更丰富高效的机制(尤其是共享内存)。在实际开发中,根据场景选择合适的通信方式至关重要。掌握这些管道通信命名管道以及System V IPC,是深入Linux编程的必经之路。

(本文插图仅为示意图,实际应用请参考具体代码)