1、无名管道有一定的局限性
–它是属于半双工的通信方式
2、管道标准库函数
$./recat
used the popen and pclose function to create a pipe !!!
–它是属于半双工的通信方式
–只有具有“亲缘关系”的的进程才能使用这种通信方式,也就是父进程和子进程之间。
2、man 2 pipe
3、int pipe(int pipefd[2])
–参数pipefd[0]:用于读管道
–参数pipefd[1]:用于写管道
–返回值:执行成功返回0,失败返回-1
例:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
//进程读函数
void read_data(int *);
//进程写函数
void write_data(int *);
int main(int argc,char *argv[])
{
int pipes[2],rc;
pid_t pid;
rc = pipe(pipes); //创建管道
if(rc == -1){
perror("\npipes\n");
exit(1);
}
pid = fork(); //创建进程
switch(pid){
case -1:
perror("\nfork\n");
exit(1);
case 0:
read_data(pipes); //相同的pipes
default:
write_data(pipes); //相同的pipes
}
return 0;
}
//进程读函数
void read_data(int pipes[])
{
int c,rc;
//由于此函数只负责读,因此将写描述关闭(资源宝贵)
close(pipes[1]);
//阻塞,等待从管道读取数据
//int 转为 unsiged char 输出到终端
while( (rc = read(pipes[0],&c,1)) > 0 ){
putchar(c);
}
exit(0);
}
//进程写函数
void write_data(int pipes[])
{
int c,rc;
//关闭读描述字
close(pipes[0]);
while( (c=getchar()) > 0 ){
rc = write( pipes[1], &c, 1); //写入管道
if( rc == -1 ){
perror("Parent: write");
close(pipes[1]);
exit(1);
}
}
close( pipes[1] );
exit(0);
}
2、管道标准库函数
#include<stdio.h>
FIFE *popen(const char *command, const char *mode)
int pclose(FIFE *stream);
command:参数command是一个在shell中可运行的命令字符串的指针,参数mode是一个字符指针,这个参数只有两种值可以使用,r或者w,分别表示popen()函数的返回值是一个读打开文件指针,还是写打开文件指针。当函数失败时返回值为NULL,并设置出错变量errno。
popen函数先执行创建一个管道,然后调用fork()函数创建子进程紧接着执行一个exec()函数调用,调用/bin/sh-c来执行参数command中的命令字符串,然后函数返回一个标准的I/O文件指针。
例:
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
#include<fcntl.h>
#include<limits.h>
#define BUFSE PIPE_BUF
int main(void)
{
FIFE *fp;
char *cmd = "cat file1" ;
char buf[BUFSZ];
if(fp = popen(cmd,"r") == NULL)
{
perroe("failed to popen");
exit(1);
}
while((fgets(buf,BUFSZ,fp)) != NULL);
printf("%s",buf);
pclose(fp);
exit(1);
}
$ recat.c -o react
$./recat
used the popen and pclose function to create a pipe !!!