#include<unistd.h>
int pipe(int fd[2]);
实际步骤:
- 创建管道(fd[0]和fd[1]);
- fork;
- 父进程关闭管道的读出端口(fd[0]);
- 子进程关闭管道的写入端口(fd[1])。
数据流向:
用户态中的父进程 ---> 内核中的管道 ---> 用户态中的子进程
编程实现单向管道(单双工):
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>
#define MAXSIZE 1024
int main(int argc, char **argv)
{
int fd[2];
pid_t childpid;
int len;
char buffer[MAXSIZE];
if(pipe(fd)<0)//initialize pipe
{
perror("pipe()");
exit(1);
}
childpid=fork();//fork a child process
if(childpid<0)
{
perror("fork()");
exit(1);
}
if(childpid==0)//child process
{
close(fd[1]);
len=read(fd[0],buffer,MAXSIZE);
puts(buffer);
close(fd[0]);
exit(0);
}
else//parent process
{
close(fd[0]);
write(fd[1],"hello world",12);
close(fd[1]);
wait(NULL);
exit(0);
}
}
全双工管道:
可以使用单个全双工管道实现双向通信.
Unix网络编程卷2中的程序形式,在默认提供半双工管道的Unix系统中会出错:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>
#define MAXSIZE 1024
int main(int argc, char **argv)
{
int fd[2],n;
char c;
pid_t childpid;
pipe(fd);
if((childpid=fork())==0)//child process
{
sleep(3);
if((n=read(fd[0],&c,1))!=1)
{
perror("read()");
}
printf("child read %c\n",c);
write(fd[0],"c",1);
exit(0);
}
//parent process
write(fd[1],"p",1);
if((n=read(fd[1],&c,1))!=1)
{
perror("read()");
}
printf("parent read %c\n",c);
exit(0);
}
全双工管道的真正实现:由两个半双工管道实现,从fd[1]写入的数据只能从fd[0]中读出,从fd[0]中写入的数据也只能从fd[1]中读出。
popen和pclose函数:
#include<stdio.h>
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);
这两个函数应用于Linux执行shell命令的场景。
函数popen先执行fork,然后调用exec以执行command,并且返回一个要么指向子进程的stdout,要么指向stdin的文件指针:
若type是”r”,则文件指针是连接到子进程执行command命令的标准输出;
如果type是”w”,则文件指针连接到子进程执行command命令的标准输入。
转自:https://blog.csdn.net/qq_29344757/article/details/70925123的例子:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>
#define MAXSIZE 1024
int main(int argc, char **argv)
{
FILE *fp1,*fp2;
char buffer[MAXSIZE];
int n;
fp1=popen("cat /etc/group","r");
fp2=popen("grep root","w");
while((n=fread(buffer,1,sizeof(buffer),fp1))>0)
{
fwrite(buffer,1,n,fp2);
}
pclose(fp1);
pclose(fp2);
}