当前位置:首页>Linux>C 语言 019 | Linux 进程间通信

C 语言 019 | Linux 进程间通信

  • 2026-10-11 06:45:36
C 语言 019 | Linux 进程间通信
上一期讲了 Linux 信号处理。
这一期我们来学习 Linux 进程间通信。

一、进程间通信

请在微信客户端打开

进程间通信就是不同进程之间交换数据的过程。因为每个进程都有自己独立的虚拟地址空间,一个进程不能直接访问另一个进程的内存,所以必须通过操作系统提供的机制来进行通信。
Linux 系统提供了多种进程间通信的方式:

管道(Pipe)和命名管道(FIFO)

信号(Signal)

共享内存(Shared Memory)

消息队列(Message Queue)

信号量(Semaphore)

套接字(Socket)

二、管道(Pipe)

管道是 Linux 中最古老、最简单的进程间通信方式,用于有亲缘关系的进程之间(比如父子进程、兄弟进程)的通信。

1. 管道的特点

半双工通信:数据只能在一个方向上流动,要么从父进程流向子进程,要么从子进程流向父进程

只能用于有亲缘关系的进程之间

数据一旦被读出,就从管道中消失了

管道的大小是有限的,默认是 4KB

2. pipe 函数:创建管道

pipefd:输出参数,返回两个文件描述符

返回值:成功返回 0,失败返回 - 1

3. 管道的工作原理

pipe 函数创建一个管道,返回两个文件描述符。父进程 fork 出子进程后,父子进程都拥有这两个文件描述符。如果我们要实现父进程写、子进程读,那么父进程需要关闭 pipefd [0],子进程需要关闭 pipefd [1]。

示例:父子进程通过管道通信

运行结果:

三、管道的读写特性

1. 读管道

如果管道的写端已经关闭,那么 read 会返回 0,表示读到了文件末尾

如果管道的写端没有关闭,并且管道中没有数据,那么 read 会阻塞,直到有数据可读

如果管道中有数据,那么 read 会立即返回实际读到的字节数

2. 写管道

如果管道的读端已经关闭,那么写操作会导致进程收到 SIGPIPE 信号,默认动作是终止进程

如果管道的读端没有关闭,并且管道已满,那么 write 会阻塞,直到有空间可写

如果管道有空间,那么 write 会立即返回实际写入的字节数

四、命名管道(FIFO)

管道只能用于有亲缘关系的进程之间,而命名管道(也叫 FIFO)可以用于任意两个进程之间的通信。
命名管道是一种特殊类型的文件,它在文件系统中有一个对应的路径名。不同的进程可以通过打开这个文件来进行通信。

1. 创建命名管道

方法一:用 mkfifo 命令创建

执行这个命令后,当前目录下会出现一个名为 myfifo 的文件,类型是 p。

方法二:用 mkfifo 函数创建

pathname:命名管道的路径名

mode:文件权限,比如 0644

返回值:成功返回 0,失败返回 - 1

2. 命名管道的使用

命名管道的使用和普通文件一样,用 open 打开,用 read 和 write 读写,用 close 关闭。

写端程序:fifo_write.c

读端程序:fifo_read.c

3. 运行测试

编译两个程序:

打开两个终端,第一个终端运行读端:
第二个终端运行写端:
此时第一个终端会显示:
注意:打开命名管道时,读端和写端会互相等待。如果只有读端打开,那么 open 会阻塞,直到有写端打开;反之亦然。

五、实战:用管道实现简单的进程间聊天程序

编译运行这个程序,就可以在父进程和子进程之间互相发送消息了。

六、总结

这一期我们学习了 Linux 进程间通信的两种方式:管道(Pipe):用于有亲缘关系的进程之间的半双工通信pipe 函数:创建管道,返回两个文件描述符管道的读写特性:阻塞、EOF 等命名管道(FIFO):用于任意进程之间的通信mkfifo 命令和函数:创建命名管道命名管道的使用:和普通文件一样打开、读写、关闭实战:用两个管道实现全双工的父子进程聊天程序
下一期讲更高效的进程间通信方式:共享内存和消息队列。
大家有任何不懂的地方,或者敲代码遇到了 bug,都可以在评论区留言,我都会一一回复。如果这篇内容对你有帮助,别忘了点赞、在看、转发给身边同样在学 C 语言的朋友。
我们下期见。

最新文章

随机文章