C语言/操作系统学习笔记——管道通信
2015-11-01 23:27
417 查看
管道通信
管道:
就像现实中的水管,水就像数据。
管道是一种半双工的通信方式
数据只能单向流动,而且只能在具有共同祖先的进程间使用。
所谓半双工的模式(以下是我的理解):
形象来说类似一个单刀双掷开关,有两个选择,但是二者是互斥的,当选择了一方另一方就失效。
而对于此处的管道,可以把它想成是管道的一端,一次只能调用一种功能读入或者写入,二者也是互斥的。
同时对应的fd[0]与fd[1]其实是一个类似一个临界区的资源,一次只能由一个进程使用一种功能,所以使用时要注意分配读和写的功能。
函数介绍:
¢int read(intfd,
void *buf,
int count);
功能:从参数fd指定的读端读取管道数据到大小为count的缓存buf中,返回实际读取到的字节数。
参数
¢fd:管道读端
¢buf:缓存区,保存读到的数据
¢count:读取字节数
•intwrite(intfd,
void *buf,
intcount);
•功能:向参数fd指定的写端从缓存buf中取出count个字节到管道中,返回值为实际写入的字节数。
•参数
•fd:管道写端
•buf:缓存区,将要写入管道的数据
•count:写入的字节数
以下是一个小的实验:
¢1.父进程创建管道和两个子进程p1和p2
¢2.子进程p1打开给定文件(如果没有,则创建文件),并向文件中写数据,写完关闭文件,然后向管道写入一条消息“ok",目的是通知进程p2可以读取文件内容了。
¢3.子进程p2通过管道读取消息,如果消息是“ok”,则打开文件,读取文件内容,并将其输出到屏幕上,关闭文件.
实现源码:
管道:
就像现实中的水管,水就像数据。
管道是一种半双工的通信方式
数据只能单向流动,而且只能在具有共同祖先的进程间使用。
所谓半双工的模式(以下是我的理解):
形象来说类似一个单刀双掷开关,有两个选择,但是二者是互斥的,当选择了一方另一方就失效。
而对于此处的管道,可以把它想成是管道的一端,一次只能调用一种功能读入或者写入,二者也是互斥的。
同时对应的fd[0]与fd[1]其实是一个类似一个临界区的资源,一次只能由一个进程使用一种功能,所以使用时要注意分配读和写的功能。
函数介绍:
¢int read(intfd,
void *buf,
int count);
功能:从参数fd指定的读端读取管道数据到大小为count的缓存buf中,返回实际读取到的字节数。
参数
¢fd:管道读端
¢buf:缓存区,保存读到的数据
¢count:读取字节数
•intwrite(intfd,
void *buf,
intcount);
•功能:向参数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; }
相关文章推荐
- C语言基础-#include
- C语言中的算术运算符和算术表达式
- leetcode笔记:Triangle
- c语言二进制八进制和十六进制的总结
- 判断闰年 2.0
- C++中的类所占内存空间总结
- C语言中指针与数组的差别
- c语言声明 void (*signal(int sig, void(*func)(int)))(int)
- 交换两个数
- c语言随机点名系统
- ——黑马程序员——C语言中字符串处理函数
- C语言版通讯录
- 【C语言】【面试题】【笔试题】.字符串替换空格:请实现一个函数,把字符串中的每个空格替换成“%20”。
- uvaoj 12097 - Pie.cpp
- 自定义乘法口诀
- C语言字符串常用操作函数-puts、gets、strcmp、strcpy、strcat、strlen
- c++中怎么把string转化为数组
- 【C语言【面试题】【笔试题】题目:在字符串中找出第一个只出现一次的字符。
- C++基础——C++风格的类型转换(static_cast、const_cast、dynamic_cast、reinterpret_cast)
- 以前整理的C++资料(二)