linux之间进程通信
2016-03-24 23:44
447 查看
进程间通信方式:
View Code
[b] 1.4有名管道的读写规则
A.从FIFO中读取数据
约定:如果一个进程为了从FIFO中读取数据而以阻塞的方式打开FIFO, 则称内核为该进程的读操作设置了阻塞标志
<1>如果有进程为写而打开FIFO,且当前FIFO内没有数据,则对于设置了阻塞标志的读操作来说,将一直阻塞。对于没有设置阻塞标志读操作来说返回-1,当前errno值为EAGAIN,提醒以后再试。
<2>对于设置阻塞标志的读操作说,造成阻塞的原因有两种:当前FIFO内有数据,但有其他进程正在读这些数据;另外就是FIFO内没有数据。解阻塞的原因则是FIFO中有新的数据写入,不论写入数据量的大小,也不论读操作请求多少数据量。
<3>如果没有进程写打开FIFO,则设置了阻塞标志的读操作会阻塞
<4>如果写端关闭,管道中有数据读取管道中的数据,如果管道中没有数据读端将不会继续阻塞,此时返回0。
注意:如果FIFO中有数据,则设置了阻塞标志的读操作不会因为FIFO中的字节数小于请求读的字节数而阻塞,此时,读操作会返回FIFO中现有的数据量。
B.向FIFO中写入数据
约定:如果一个进程为了向FIFO中写入数据而阻塞打开FIFO,那么称该进程内的写操作设置了阻塞标志。
对于设置了阻塞标志的写操作:
<1>当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。如果此时管道空闲缓冲区不足以容纳要写入的字节数,则进入睡眠,直到当缓冲区中能够容纳写入的字节数时,才开始进行一次性写操作。
<2>当要写入的数据量大于PIPE_BUF时,Linux将不再保证写入的原子性。FIFO缓冲区一有空闲区域,写进程就会试图向管道写入数据,写操作在写完所有请求写的数据后返回。
对于没有设置阻塞标志的写操作:
<1>当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。在写满所有FIFO空闲缓冲区后,写操作返回。
<2>当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。如果当前FIFO空闲缓冲区能够容纳请求写入的字节数,写完后成功返回;如果当前FIFO空闲缓冲区不能够容纳请求写入的字节数,则返回EAGAIN错误,提醒以后再写。
注意:只有读端存在,写端才有意义。如果读端不在,写端向FIFO写数据,内核将向对应的进程发送SIGPIPE信号(默认终止进程)
write to fifo
read from fifo
将write to fifo 部分中,输入一个字符串进入到buf中,再将buf中这个字符串写入到 fifo中,另一个进程再从fifo中读出数据
可以将这两个程序运行,然后输入read和write FIFO大小就可以看到效果。
参考资料:
http://blog.csdn.net/w616589292/article/details/50957456 http://www.cnblogs.com/bastard/archive/2012/08/31/2664896.html#3311781
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(int argc,char *argv[]) { int fd; if(argc < 2) { fprintf(stderr,"usage : %s argv[1].\n",argv[0]); exit(EXIT_FAILURE); } if(mkfifo(argv[1],0666) < 0 && errno != EEXIST) { fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno)); exit(EXIT_FAILURE); } if((fd = open(argv[1],O_RDONLY)) < 0) { fprintf(stderr,"Fail to open %s : %s.\n",argv[1],strerror(errno)); exit(EXIT_FAILURE); } printf("open for read success.\n"); return 0; }
View Code
[b] 1.4有名管道的读写规则
A.从FIFO中读取数据
约定:如果一个进程为了从FIFO中读取数据而以阻塞的方式打开FIFO, 则称内核为该进程的读操作设置了阻塞标志
<1>如果有进程为写而打开FIFO,且当前FIFO内没有数据,则对于设置了阻塞标志的读操作来说,将一直阻塞。对于没有设置阻塞标志读操作来说返回-1,当前errno值为EAGAIN,提醒以后再试。
<2>对于设置阻塞标志的读操作说,造成阻塞的原因有两种:当前FIFO内有数据,但有其他进程正在读这些数据;另外就是FIFO内没有数据。解阻塞的原因则是FIFO中有新的数据写入,不论写入数据量的大小,也不论读操作请求多少数据量。
<3>如果没有进程写打开FIFO,则设置了阻塞标志的读操作会阻塞
<4>如果写端关闭,管道中有数据读取管道中的数据,如果管道中没有数据读端将不会继续阻塞,此时返回0。
注意:如果FIFO中有数据,则设置了阻塞标志的读操作不会因为FIFO中的字节数小于请求读的字节数而阻塞,此时,读操作会返回FIFO中现有的数据量。
B.向FIFO中写入数据
约定:如果一个进程为了向FIFO中写入数据而阻塞打开FIFO,那么称该进程内的写操作设置了阻塞标志。
对于设置了阻塞标志的写操作:
<1>当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。如果此时管道空闲缓冲区不足以容纳要写入的字节数,则进入睡眠,直到当缓冲区中能够容纳写入的字节数时,才开始进行一次性写操作。
<2>当要写入的数据量大于PIPE_BUF时,Linux将不再保证写入的原子性。FIFO缓冲区一有空闲区域,写进程就会试图向管道写入数据,写操作在写完所有请求写的数据后返回。
对于没有设置阻塞标志的写操作:
<1>当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。在写满所有FIFO空闲缓冲区后,写操作返回。
<2>当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。如果当前FIFO空闲缓冲区能够容纳请求写入的字节数,写完后成功返回;如果当前FIFO空闲缓冲区不能够容纳请求写入的字节数,则返回EAGAIN错误,提醒以后再写。
注意:只有读端存在,写端才有意义。如果读端不在,写端向FIFO写数据,内核将向对应的进程发送SIGPIPE信号(默认终止进程)
write to fifo
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define MAX 655360 int main(int argc,char *argv[]) { int n,fd,i; char buf[MAX]="i am the buf in write"; // string temp ; if(argc < 2) { fprintf(stderr,"usage : %s argv[1].\n",argv[0]); exit(EXIT_FAILURE); } if(mkfifo(argv[1],0666) < 0 && errno != EEXIST) { fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno)); exit(EXIT_FAILURE); } if((fd = open(argv[1],O_WRONLY )) < 0) { fprintf(stderr,"Fail to open %s : %s.\n",argv[1],strerror(errno)); exit(EXIT_FAILURE); } printf("open for write success.\n"); while(1) { printf(">"); int i=0; while((buf[i]=getchar())!='\n') i++; // scanf("%s",&temp); // for(i=0;i<sizeof(temp);i++) // buf[i]=temp[i]; n = write(fd,buf,i); printf("write %d bytes.\n",n); } exit(EXIT_SUCCESS); }
read from fifo
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define MAX 20 int main(int argc,char *argv[]) { int fd,n,i; char buf[MAX]; if(argc < 2) { fprintf(stderr,"usage : %s argv[1].\n",argv[0]); exit(EXIT_FAILURE); } if(mkfifo(argv[1],0666) < 0 && errno != EEXIST) { fprintf(stderr,"Fail to mkfifo %s : %s.\n",argv[1],strerror(errno)); exit(EXIT_FAILURE); } if((fd = open(argv[1],O_RDONLY )) < 0) { fprintf(stderr,"Fail to open %s : %s.\n",argv[1],strerror(errno)); exit(EXIT_FAILURE); } printf("open for read success.\n"); while(1) { printf(">"); scanf("%d",&n); n = read(fd,buf,n); printf("Read %d bytes.\n",n); for(i=0;i<20;i++) printf("%c",buf[i]); printf("\n"); } exit(EXIT_SUCCESS); }
将write to fifo 部分中,输入一个字符串进入到buf中,再将buf中这个字符串写入到 fifo中,另一个进程再从fifo中读出数据
可以将这两个程序运行,然后输入read和write FIFO大小就可以看到效果。
参考资料:
http://blog.csdn.net/w616589292/article/details/50957456 http://www.cnblogs.com/bastard/archive/2012/08/31/2664896.html#3311781
相关文章推荐
- linux上安装maven
- linux的arp指令
- [ 脚本 ] RHEL6.x 及Centos6.x 初始化脚本
- linux 安装
- [转]在 Linux 安裝Firefox
- Linux内核设计第五周——扒开系统调用三层皮(下)
- linux中进程管理的三大工具及进程查看命令
- linux目录结构详解
- Linux 服务器安全技巧
- Makefile中的几个调试方法
- centos7上配置nexus(坑)
- 四大命令助你轻松管理Linux进程
- Beaglebone LinuxCNC starterkit: ready-to-run SD card image
- linux帐号管理
- 20135320赵瀚青LINUX第五周学习笔记
- Centos 6.5下安装图形界面
- linux vi 编辑器的使用
- linux基础命令(7)
- Linux面试题
- Linux 学习笔记 2016.03.24