11.1 进程间通信的基本概念
2025/12/16大约 3 分钟
11.1 进程间通信的基本概念
相关信息
进程间通信(Inter Process Communication - IPC)意味着两个不同的进程间可以交换数据,为了完成这一点,操作系统中应提供两个进程可以同时访问的内存空间。
- 同时访问:一个进程在修改内存时其余进程可以访问吗?
- 系统提供:进程具有完全独立的内存结构
通过管道实现进程间通信
#include <unistd.h>
int pipe(int pipefd[2]);| 参数 | 值 | 用途 | 说明 |
|---|---|---|---|
| pipefd | pipefd[0] refers to the read end of the pipe. pipefd[1] refers to the write end of the pipe | create a pipe | Data written to the write end of the pipe is buffered by the kernel until it is read from the read end of the pipe. |
- 管道中的数据只能从write端流向read端;
- write后的数据由内核(系统)缓存,直到read读取
管道的使用
实现:
先创建管道,然后创建子进程
int main(int argc, char* argv[])
{
char buf[BUF_SIZE] = {0};
int pipefd[2];
if(pipe(pipefd) == -1) {
error_handling("pipe() error");
}
pid_t pid = fork();
if(pid == -1) {
error_handling("fork() error");
}
else if(pid == 0) { // Child process
write(pipefd[1], "Hello from child", 16);
}
else{
read(pipefd[0], buf, BUF_SIZE);
printf("Parent received: %s\n", buf);
sleep(1); // Ensure child process has time to finish
}
return 0;
}| 行号 | 功能 | 说明 |
|---|---|---|
| 4-7 | 创建管道 | |
| 14 | 子进程向管道写入数据 | |
| 17-19 | 父进程读取管道中的数据 |
效果:
ming@ubuntu:/media/sf_share/Network/build$ ./Network
Parent received: Hello from child测试管道的性质
- 单向流通
实现:
向出口写入,从入口读取
write(pipefd[0], "Hello from child", 16);
read(pipefd[1], buf, BUF_SIZE);效果:
ming@ubuntu:/media/sf_share/Network/build$ ./Network
Parent received:
ming@ubuntu:/media/sf_share/Network/build$没有读取到数据
- buffered by kernel
实现:
等待多次写入,然后一次性读取
else if(pid == 0) { // Child process
write(pipefd[1], "Hello from child", 16);
write(pipefd[1], "Another message", 16);
}
else{
sleep(3);
read(pipefd[0], buf, BUF_SIZE);
printf("Parent received: %s\n", buf);
sleep(1); // Ensure child process has time to finish
}效果:
ming@ubuntu:/media/sf_share/Network/build$ ./Network
Parent received: Hello from childAnother message或者 每次读取少量数据
else if(pid == 0) { // Child process
write(pipefd[1], "Hello from child", 16);
}
else{
while(read(pipefd[0], buf, 1))
{
printf("Parent received: %s\n", buf);
}
}效果:
ming@ubuntu:/media/sf_share/Network/build$ ./Network
Parent received: H
Parent received: e
Parent received: l
Parent received: l
Parent received: o
Parent received:
Parent received: f
Parent received: r
Parent received: o
Parent received: m
Parent received:
Parent received: c
Parent received: h
Parent received: i
Parent received: l
Parent received: d通过管道进行进程间双向通信
由于管道的单向流通以及内核缓存的特性,如果父子进程间需要双向通信,只使用一个管道,那么在没有完全读取 或者 读取过程中有新的数据写入,比如父进程先读,读了5字节数据,以为读取完毕,实际又来了3个,父进程开始写入4字节。然后子进程读取。这样子进程就把自己发送给父进程的数据取出来了。
书中的示例程序是子进程 先写入,但是写入后立即进行读取,导致管道中没有数据,那么先读取的父进程就会一直等待。
解决办法:创建两个管道,每个管道各自负责不同的数据流动