在前几篇文章当中我们为大家详细的讲述了进程和线程基本和进阶应用,那么不同的进程和线程当中如果我们进行数据的交互,或者信息的访问,我们应该采取什么办法呢?
那么本文将为大家讲述进程间的通信方式-----管道中的无名管道
管道分为无名管道和有名管道
- 无名管道 ===》pipe ==》只能给有亲缘关系进程通信
- 有名管道 ===》fifo ==》可以给任意单机进程通信
管道的特性:
- 管道是 半双工的工作模式
- 所有的管道都是特殊的文件不支持定位操作。(lseek->> fd fseek ->>FILE* )
- 管道是特殊文件,读写使用文件IO。(open,read,write,close)
使用框架:
- 创建管道 == 》 读写管道 ==》关闭管道
1.创建管道
int pipe(int pipefd[2]);
- 功能:创建并打开一个无名管道
- 参数:
- pipefd[0] ==>无名管道的固定读端
- pipefd[1] ==>无名管道的固定写端
- 返回值:
- 成功 0
- 失败 -1
2.读写管道
把pipefd当作文件描述符进行操作,pipefd[0] ==>无名管道的固定读端,pipefd[1] ==>无名管道的固定写端,pipefd的位置是固定的,在使用时要记得
3.关闭管道
close pipefd[0];
close pipefd[1];
关闭管道也没有特殊的函数接口,和关闭文件描述符一样,在文件IO的操作里运用close的指令操作。
代码示例:
int main(int argc, const char *argv[]) { int pipefd[2]; int ret = pipe(pipefd); if(ret < 0) { perror("fail to pipe\n"); return -1; } pid_t pid = fork(); if(pid > 0) { close(pipefd[0]); while(1) { char buff[1024] = {0}; fgets(buff, sizeof(buff), stdin); write(pipefd[1], buff, strlen(buff)+1); if(0 == strcmp(buff, "quit\n")) { break; } } wait(NULL); close(pipefd[1]); } else if(0 == pid) { close(pipefd[1]); while(1) { char buff[1024] = {0}; read(pipefd[0], buff, sizeof(buff)); if(0 == strcmp(buff, "quit\n")) { break; } printf("your write:%s", buff); } close(pipefd[0]); } else { perror("fail to fork\n"); return -1; } return 0; }
以上代码就是在父子进程中使用了pipe管道进行父子进程间的通信,父进程终端输入内容,在子进程中可以打印出来并且quit退出,以上要注意pipefd[0]和pipefd[1]端口的读写顺序,pipefd类似于文件描述符,要用文件IOwrite和read进行读写,用后记得关闭管道pipefd,避免浪费资源