进程间通信——管道
来源:互联网 发布:js 三个等号 编辑:程序博客网 时间:2024/05/21 13:28
用管道来进行进程间通信是通过pipe函数,管道只能支持父子进程或有公共祖先的进程之间通信。
pipe函数原型:
#include <unistd.h>int pipe (int fd[2]);该函数被调用后,会通过fd数组传出两个文件描述符fd[0]和fd[1],其中fd[0]为读而打开,fd[1]为写而打开。从fd[0]中读的数据,就是往fd[1]中写的数据。
当父进程调用fork后,子进程继承了父进程的文件描述符fd[0]和fd[1]。这样就建立了父子进程之间的IPC通道。父进程往fd[1]中写数据时,子进程就可以通过fd[0]读到。
下面代码描述的是上图的流程
父进程
1:fork出自进程
2:从标准输入读入数据
3:将数据通过fd[1]写入管道
子进程
1:通过fd[0]从管道读入数据
2:将数据写到标准输出
#include <stdio.h>#include <unistd.h>int main () {int buflen;char* buffer[1024];pid_t pid;int fd[2];if (pipe(fd) < 0) {printf ("pipe error\n");return 1;}if ((pid = fork()) < 0) {printf ("pipe error\n");return 1;}if (pid > 0) { //fatherclose (fd[0]);while ((buflen = read (STDIN_FILENO, buffer, 1024)) > 0) {write (fd[1], buffer, buflen);}return 0;}else {close (fd[1]);while ((buflen = read (fd[0], buffer, 1024)) > 0) {write (STDOUT_FILENO, buffer, buflen);}return 0;}}
图中1 2 3 4 5 6分别为:
1是父进程标准输入(STDIN_FILENO)
2是父进程的fd1[1]
3是子进程的fd1[0],同时也是子进程的标准输入
4是子进程的fd2[1],同时也是子进程的标准输出
5是父进程的fd2[0]
6是父进程的标准输出(STDOUT_FILENO)
父进程流程:
1:fork创建子进程
2:主循环中不断从标准输入中读取数据
3:通过fd1[1]将读入的数据写入管道
4:通过fd2[0]从管道中读入数据
5:将数据写到标准输出
子进程流程:
1:调用dup2函数复制文件描述符fd1[0]为标准输入
2:复制文件描述符fd2[1]为标准输出
3:调用execl函数执行新的程序coproces,进入coproces主循环,该程序由coproces.c编译而成,功能是英文字符大小写转换。
4:在coproces主循环中不断从标准输入读取数据
5:将数据中英文字符大小写转换后写入标准输出。
// coproces.c
#include <stdio.h>#include <unistd.h>int main () {char buffer[1024];int buflen;while ((buflen = read (STDIN_FILENO, buffer, 1024)) > 0) {int i = 0;for (i = 0; i < buflen; ++i) {if (isupper (buffer[i])) {buffer[i] = tolower (buffer[i]);}else if (islower (buffer[i])) {buffer[i] = toupper (buffer[i]);}}write (STDOUT_FILENO, buffer, buflen);}}
// main.c
#include <stdio.h>#include <unistd.h>#include <stdlib.h>int main () {pid_t pid;int fd1[2], fd2[2];int buflen;char buffer[1024];if (pipe (fd1) < 0 || pipe (fd2) < 0) {printf ("pipe error!\n");exit (1);}if ((pid = fork()) < 0) {printf ("fork error !\n");exit (1);}if (!pid) { // child processclose (fd1[1]); // read onlyclose (fd2[0]); // write onlyif (STDIN_FILENO != fd1[0]) {if(STDIN_FILENO !=dup2 (fd1[0], STDIN_FILENO)) {printf ("error!\n");exit (1);}close (fd1[0]);}if (STDOUT_FILENO != fd2[1]) {if(STDOUT_FILENO != dup2 (fd2[1], STDOUT_FILENO)) {printf ("error!\n");exit (1);}close (fd2[1]);}if (execl ("./coproces", "coproces",(char*)0) < 0) {printf ("execl error\n");exit (1);}}// parent processclose (fd1[0]); //write onlyclose (fd2[1]); //read onlywhile ((buflen = read (STDIN_FILENO, buffer, 1024)) > 0) {if (buflen != write (fd1[1], buffer, buflen)) {printf ("write to fd1 error!\n");exit (1);}buflen = read (fd2[0], buffer, 1024);write (STDOUT_FILENO, buffer, buflen);}exit (0);}
- 进程间通信—管道
- 进程间通信—管道
- 进程间通信—管道
- 进程间通信——管道通信
- 进程间通信——管道通信
- Windows进程间通信——管道
- 进程间通信——管道(Pipe)
- Linux进程间通信——管道
- 进程间通信——匿名管道
- Linux进程间通信——管道
- Linux进程间通信——管道
- 进程间通信——管道
- 进程间通信——管道
- 进程间通信——管道
- 进程间通信——管道
- 进程间通信——管道
- 进程间通信 ——管道
- 进程间通信——管道
- 1. ORACLE内存全面解析
- 视图层以及模板引擎
- DirectX 3D_实践之DirectX3D光照的实现
- Oracle OCI :OCI程序设计流程
- uva 11520 - Fill the Square(枚举,2级)
- 进程间通信——管道
- ThinkPHP_常见系统变量
- GTK编程入门
- poj 3181 Dollar Dayz
- C/C++程序员实用大全学习笔记之(1):对数组应用取地址运算符&
- 黑马程序员-高新技术(类加载器)
- UVa 10132 - File Fragmentation
- Magento中直接使用SQL语句
- 在任何设备上都完美呈现的30个华丽的响应式网站