管道通信
管道:
就像现实中的水管,水就像数据。
管道是一种半双工的通信方式
数据只能单向流动,而且只能在具有共同祖先的进程间使用。
所谓半双工的模式(以下是我的理解):
形象来说类似一个单刀双掷开关,有两个选择,但是二者是互斥的,当选择了一方另一方就失效。
而对于此处的管道,可以把它想成是管道的一端,一次只能调用一种功能读入或者写入,二者也是互斥的。
同时对应的fd[0]与fd[1]其实是一个类似一个临界区的资源,一次只能由一个进程使用一种功能,所以使用时要注意分配读和写的功能。
函数介绍
:
所谓半双工的模式(以下是我的理解):
形象来说类似一个单刀双掷开关,有两个选择,但是二者是互斥的,当选择了一方另一方就失效。
而对于此处的管道,可以把它想成是管道的一端,一次只能调用一种功能读入或者写入,二者也是互斥的。
同时对应的fd[0]与fd[1]其实是一个类似一个临界区的资源,一次只能由一个进程使用一种功能,所以使用时要注意分配读和写的功能。
¢
int
read(
int
fd
, void *
buf
,
int
count);
功能:从参数
fd
指定的读端读取管道数据到大小为
count
的缓存
buf
中,返回实际读取到的字节数。
参数
¢
fd
:
管道读端
¢
buf
:
缓存区,保存读到的数据
¢
count:
读取字节数
•
int
write(
int
fd
, void
*
buf
,
int
count
);
•
功能:向
参数
fd
指定的写端从缓存
buf
中取出
count
个字节到管道
中
,
返回
值为实际写入的字节数
。
•
参数
•
fd
:
管道写端
•
buf
:
缓存区
,将要写入管道的数据
•
count:
写入的字节
数
以下是一个小的实验:
¢
1.
父进程创建管道和两个子进程
p1
和
p2
¢
2.
子进程
p1
打开给定文件(如果没有,则创建文件),并向文件中写数据,写完关闭文件,然后向管道写入一条消息“
ok"
,目的是通知进程
p2
可以读取文件内容了。
¢
3.
子进程
p2
通过管道读取消息,如果消息是“
ok”,
则打开文件,读取文件内容,并将其输出到屏幕上
,
关闭文件
.
实现源码:
//@Athor:Ruihong Yao
//@Date:2015/10/31
//Using a pipe to send message between two processes
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
int main()
{
//
//printf("------------");
int fd[2],nbytes;
char string[]="OK";
//a buffer and a local file
char buffer[100],ch;
FILE *file1,*file2;
//pipe id
pipe(fd);
int w_fd=fd[1];
int r_fd=fd[0];
//create a subprocess
pid_t pid=fork();
if(pid==0){
close(r_fd);//close the read_right
if((file1=fopen("1.txt","r"))==NULL){
perror("Open file fail");
exit(-1);
}
else{
printf("---------The file exist!-------\n");
fclose(file1);
//send acknowledge message "OK" to the pipe
write(w_fd,string,strlen(string));
exit(0);
}
}else if(pid>0){
if((file2=fopen("1.txt","r"))==NULL){
perror("Open file fail");
exit(-1);
}
close(w_fd);
//get the message
read(r_fd,buffer,sizeof(buffer));
if(buffer[0]=='O'&&buffer[1]=='K'){
printf("--------file content is:---------");
//read message from the file
ch=fgetc(file2);
printf("\n%c",ch);
while(ch!=EOF){
ch=fgetc(file2);
if(ch!=EOF)
printf("%c",ch);
}
}
fclose(file2);
}
else{
perror("Fork error!");
exit(-1);
}
wait(0);
return 0;
}