在Shell命令中,如rpm -qa|grep telnet 。其中rpm -qa命令 (进程)的输出将作为grep telnet命令的输入。连接输入输出的中间设备即为一个管道文件。因此,使用管道可以将一个命令的暑促作为另一个命令输入(在运行时,一个命令将创建一个进程),而这种管道是临时的,当命令执行完成后,将自动消失,这里管道称为无名管道。
无名管道只能是具有亲缘关系的进程间通信(fd的继承),完成后自动消失。有名管道和普通文件类似,但其存储的信息待通信的两个进程结束后消失。
无名管道
C++ Code
1
2 3 4 5 6 7 8 9 |
int pipe(
int _pipedes[
2])
// pipedes[0]:读管道的文件描述符 pipedes[ 1]: //写管道的文件描述符 sszie_t read( int fd, void *buf, size_t _nbytes) // Note:若管道为空将阻塞 sszie_t write( int fd, void *buf, size_t _nbytes) //Note:若管道已满将阻塞 //管道大小限制:PIPE_BUF=4096 |
文件重定向
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 |
//fd = 0, 1, 2对应于标准输入,标准输出,错误输出 //输入重定向:</<< // Ex:cat<in.txt //输出重定向:>/>> // Ex:cat>out.txt<in.txt //复制文件描述符: // 共享file_struct int dup( int _fd) // Fun:将fd复制到可用的最小的fd // Ret:被复制了的fd int dup2( int _fd, int _fd2) // Fun:fd复制给fd2 // Ret:error:-1 |
流重定向
C++ Code
1
2 3 4 5 6 7 |
FILE *popen(
const
char *command, _const
char *_modes)
//modes: //r:命令执行的输出结果可以从file中读 //w:命令执行的输入从file中写入 int pclose(FILE *stream) //执行完后要关闭file文件 |
下面是使用无名管道进行进程间通信的一个例子:
在此程序中子进程写入数据,在父进程中读取数据。
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#include <iostream>
using namespace std; #include<unistd.h> #include<stdio.h> #include<stdlib.h> int main( int argc, char *argv[]) { pid_t pid; int temp; int pipedes[ 2]; char s[ 14] = "test message!"; char d[ 14]; if(pipe(pipedes) == - 1) //创建管道 { perror( "pipe"); exit(EXIT_FAILURE); } if((pid = fork()) == - 1) //创建新的进程 { perror( "fork"); exit(EXIT_FAILURE); } else if(pid == 0) //子进程 { printf( "now,write data to pipe\n"); if(write(pipedes[ 1], s, 14) == - 1) //写数据到管道 { perror( "write"); exit(EXIT_FAILURE); } else { printf( "the written is : %s\n", s); exit(EXIT_SUCCESS); } } else if(pid > 0) //父进程 { sleep( 2); //休眠2秒,让子进程先执行 printf( "now read the pipe\n"); if((read(pipedes[ 0], d, 14)) == - 1) //读数据 { perror( "read"); exit(EXIT_FAILURE); } printf( "the data form pipe is %s\n", d); } return 0; } |