Linux|进程间通信——管道

基于管道的进程间通信模型
Linux|进程间通信——管道
文章图片

为了完成进程间通信,需要先建立管道。管道不属于进程的资源而是和套接字一样属于操作系统。两个进程通过操作系统提供的内存空间进行通信。
创建管道的API:

#include //成功返回 0,失败返回 -1 int pipe(int filedes[2]);

接口参数为文件描述符组成的数组。filedes[0]管道出口,filedes[1]管道入口。
进程间通关管道简单通信示例:
#include #include int main() { int fds[2]; char str[] = "How are you!"; char buff[128] = {0}; pid_t pid; //创建通信管道 if(pipe(fds) == -1) { printf("Error pipe!\n"); return 0; }pid = fork(); if(pid == 0) { //子进程向管道写数据 write(fds[1], str, sizeof(str)); } else { //父进程从管道读数据 read(fds[0], buff, 128); puts(buff); } return 0; }

子进程拿到fds[1]向里面写数据,父进程拿到fds[0]从里面读数据,模型就像下图这样:
Linux|进程间通信——管道
文章图片

需要注意的是管道中的数据是无主的。也就说任何进程拿到了fds[0]都可以从里面读数据;任何进程拿到了fds[1],都可以向里面写数据。模型如下图:
Linux|进程间通信——管道
文章图片

这个模型下是保证不了消息的属主的,子进程可能读到的是自己放入管道的消息,也可能是父进程放入管道的消息;父进程亦然。
【Linux|进程间通信——管道】如果要保证全双工通信,则必须用两个管道,模型如下:
Linux|进程间通信——管道
文章图片

#include #include int main() { int fds1[2]; int fds2[2]; char pstr[] = "Parant process sends message!\n"; char cstr[] = "Child process sends message!\n"; char buff[32] = {0}; if(pipe(fds1) == 0 && pipe(fds1) == 0) { } else { printf("Error pipe(fds)!\n"); return 0; } pid_t pid; pid = fork(); if(pid == 0)//子进程 用 fds[1]写,用fds1[0]读。父进程用fds1[1]写,用fds2[0]读。 { write(fds1[1], cstr, sizeof(cstr)); //sleep(1); read(fds2[0], buff, sizeof(buff)); puts(buff); } else { read(fds1[0], buff, sizeof(buff)); puts(buff); write(fds2[1], pstr, sizeof(cstr)); sleep(3); } return 0; }

    推荐阅读