进程间的通信--(一)管道
来源:互联网 发布:注册域名后如何使用 编辑:程序博客网 时间:2024/05/21 17:30
进程间的通讯方式有很多种:管道通信,共享内存,消息队列,信号量、远程过程调用,以及网络部分的通过套接字(socket)来通讯,首先我们来了解一下管道通信。
一、管道
引入:在现实中的一些管道,比如水管、气管都起着运输作用,在进程通信中管道也起着对信息数据的承载运输作用,所谓管道通信就是开辟一块空间,进程在里面进行读写(如图一所示),这一块空间就是我们所说的管道文件,那管道文件和我们普通的文件有什么不同呢?为什么我们不能开辟一个普通文件进行读写呢?
基本信息:通信分为半双工通信、全双工通信。半双工通信就是指通信双方不能同时进行通信,只能一段发送一端接收,全双工通信是指通信双方即可发送消息也可接收消息。我们现在所说的管道通信就是半双工通信。之所以把管道设为半双工通信原因:A进程既可写可读,B可读的情况,当A写入一个数据时,读数据所读取的数据也可能是自己写入的数据,没有意义。
类别:管道分为有名管道和无名管道
1、有名管道:应用于任意两个进程之间的单向传递,文件目录树(在磁盘中存储)中有一个标识,仅仅占用了一个结点,没有占用磁盘上的任何内存,在使用中数据缓存在内存里,只在使用时开辟内存,读取一次后自动清空。
注:Linux文件系统中,每一个存放在磁盘上的文件由两部分组成:数据块:实际存放文件数据的磁盘块;inode:Linux内部用于描述文件特性的数据结构。inode含有关于文件的大部分信息,包括文件数据块。
不使用普通文件的原因:普通文件从磁盘进行io操作,耗费时间;管道是在内存上重新开辟一块空间,读写数据时,直接在内存上读取
2、无名管道:
定义:相对于有名管道,使用时产生,不使用时释放,不在系统上有任何痕迹,无名管道因其没有任何标识,所以只能应用于父子进程之间,子进程会拷贝父进程的文件表数组,其拷贝是浅拷贝,只是定义了一个指针,其共享一个文件描述符
使用:
1、有名管道
创建:(以命令方式)mkfifo +文件名 函数方式 谁调用命令
打开:open以只写打开管道文件时,没有文件以读/读写方式大开时,函数不返回
写入:write(fd,buff,size);
读取:read(fd,buff,size);读取数据并把数据清空??memset
关闭:close(fd);
2、无名管道
创建打开:(以函数方式)int pipe(int fd[2])形参加中括号相当于指针
fd[0] ,读 fd[1]写,实质上是一个文件描述符指向文件
写write(fd[0],buff,size)
读read(fd[1],buff,len)
关close(fd[1]);close(fd[0]);
代码:有名管道
写端代码:
#include<stdio.h> #include<fcntl.h> #include<string.h> #include<unistd.h> #include<stdlib.h> #include<assert.h> void main() { int fd=open("FIFO",O_WRONLY); assert(fd!=-1); printf("open success\n"); char buff[128]={0}; while(1) { printf("please input:"); fgets(buff,128,stdin); write(fd,buff,strlen(buff)-1); if(strncmp(buff,"end",3)==0) { exit(0); } } close(fd); }读端:
#include<stdio.h>#include<fcntl.h>#include<string.h>#include<assert.h>#include<stdlib.h>#include<unistd.h>void main(){ int fd=open("FIFO",O_RDONLY); assert(fd!=-1); printf("open success\n"); char buff[128]={0}; int count=0; while(1) { read(fd,buff,127); printf("read: %s\n",buff); count++; if(strncmp(buff,"end",3)==0) { printf("word number:\n",count); break; } } close(fd); }无名管道:
#include<stdio.h>#include<fcntl.h>#include<string.h>#include<unistd.h>#include<stdlib.h>#include<assert.h> void main() { int fd[2]={0}; int pipe1=pipe(fd); pid_t pid=fork(); if(pid==0) { close(fd[1]); //printf("this is child\n"); char buff[128]={0}; while(1) { read(fd[0],buff,127); printf("read:%s\n",buff); if(strncmp(buff,"end",3)==0) { break; } } } else { // printf("this is parent\n") close(fd[0]); while(1) { char buff[128]={0}; printf("please input:\n"); fgets(buff,128,stdin); write(fd[1],buff,strlen(buff)-1); if(strncmp(buff,"end",3)==0) { break; } sleep(3); } } close(fd[1]); close(fd[2]); }未解决问题:把管道文件的标识符放在磁盘上?为什么
磁盘,内存存储方式
管道的默认值是多少?能不能修改管道大小?
管道操作的内核实现(空间的大小,读写偏移量的变化 )
- 进程间的通信--(一)管道
- 进程间通信的方式(一):管道
- Linux进程间通信(一):管道
- 进程间通信(一) :管道
- Linux进程间通信(一)管道
- 进程间通信(一)—管道
- 进程间通信(一)-----管道
- 进程间通信(一)无名管道
- 进程间通信方式(一)管道
- linux进程间通信(一)管道和命名管道
- Linus进程间通信(一)管道、命名管道的原理及实现
- Linux--进程间通信(一)-管道(pipe)通信
- 进程间通信之管道通信(一)
- 进程间的通信(管道)
- 进程间的通信:管道
- 进程间的通信:管道
- 进程间通信(管道)
- Linux环境进程间通信(一)——管道
- 例题7-11 宝箱(Zombie's Treasure Chest, Shanghai 2011, UVa12325)
- Palindrome URAL
- 用hibernate5进行查询时获取单个结果问题
- 欢迎使用CSDN-markdown编辑器
- 链表各类操作详解
- 进程间的通信--(一)管道
- vc向richedit控件写RTF格式内容(表格)
- Windows编程基础--第4节 MFC消息映射机制
- 求最大公因数和最小公倍数
- TexturePacker的强大功能
- UE4 IOS打包详解
- LeetCode.153 Find Minimum in Rotated Sorted Array
- mysql服务器的优化思路
- 景德镇浮梁镇一户村民在建房打地基时发现几吨古钱(图)