PIPE 函数
解释: 该函数是用来创建父子进程的管道的
int pipe(int pipefd[2]); 成功:0;失败:-1,设置errno
函数调用成功返回r/w两个文件描述符。无需open,但需手动close。规定:fd[0] → r; fd[1] → w,就像0对应标准输入,1对应标准输出一样。向管道文件读写数据其实是在读写内核缓冲区。
创建该管道的进程(父进程)同时掌握着管道的读端和写端.
实现父子进程的通信如下面三步骤
1. 父进程调用pipe函数创建管道,得到两个文件描述符fd[0]、fd[1]指向管道的读端和写端。
2. 父进程调用fork创建子进程,那么子进程也有两个文件描述符指向同一管道。
3. 父进程关闭管道读端,子进程关闭管道写端。父进程可以向管道中写入数据,子进程将管道中的数据读出。由于管道是利用环形队列实现的,数据从写端流入管道,从读端流出,这样就实现了进程间通信。
可以参考下图:
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<wait.h>
int main(){
int fd[2];
int result = pipe(fd);
if(result == -1){
printf("pipe create fail!\n");
}else{
printf("pipe create success!\n");
}
//使用完管道需要关闭读端fd[0]和写端fd[1]
close(fd[0]);
close(fd[1]);
return 0;
fork()函数
函数原型编辑
pid_t fork( void);
(pid_t 是一个宏定义,其实质是int 被定义在#include<sys/types.h>中)
返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1
应用实例:fork() 产生两个 生产者进程和 两个消费者进程,生产者与消费者进程之间通过 pipe() 相互联系
代码(C语言):
#include<unistd.h>
#include<errno.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/file.h>
#include<sys/wait.h>
int fd[2];
char buf[1024];
char news[1024];
void product(int pid){
printf("product %d is running!\n",pid);
close(fd[0]);
for(int i = 0;i<5;i++){
sleep(2);
if(pid==1) strcpy(news,"product 1 is running!\0");
else strcpy(news,"product 2 is running!\0");
write(fd[1],buf,strlen(news)+1);
}
printf("producter %d is over!\n",pid);
close(fd[1]);
}
void customer(int pid){
printf("customer %d is running!\n",pid);
close(fd[1]);
for(int i = 0; i<5;i++){
sleep(2);
if(pid == 1) strcpy(news,"customer 1 is running!\0");
else strcpy(news,"customer 2 is running!\0");
int len = read(fd[0],buf,strlen(news));
write(STDOUT_FILENO,buf,len+1);
}
printf("customer %d is over!\n",pid);
close(fd[0]);
}
int main(){
pid_t p1,p2,c1,c2;
int result=pipe(fd);
if(result<0){
printf("create pipe fail!\n");
exit(-1);
}else{
printf("create pipe success!\n");
if((p1=fork())==0)
product(1);
if((p2=fork())==0)
product(2);
if((c1=fork())==0)
customer(1);
if((c2=fork())==0)
customer(2);
}
close(fd[0]);
close(fd[1]);
for(int i = 0;i<4;i++)
wait(NULL);
return 0;
}