C语言/操作系统学习笔记——管道通信

时间:2022-02-28 17:41:34

管道通信

C语言/操作系统学习笔记——管道通信

管道:
— 就像现实中的水管,水就像数据。
— 管道是一种半双工的通信方式
— 数据只能单向流动,而且只能在具有共同祖先的进程间使用。

所谓半双工的模式(以下是我的理解):
形象来说类似一个单刀双掷开关,有两个选择,但是二者是互斥的,当选择了一方另一方就失效。
而对于此处的管道,可以把它想成是管道的一端,一次只能调用一种功能读入或者写入,二者也是互斥的。
同时对应的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: 写入的字节

以下是一个小的实验:

C语言/操作系统学习笔记——管道通信

¢ 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;
}