Linux环境进程间通信(一):管道及有名管道(3)

2019-08-20 19:01

{ if(errno==EAGAIN) printf(\ } else printf(\ real_wnum=write(fd,w_buf,5000); //5000用于测试写入字节大于4096时的非原子性 //real_wnum=write(fd,w_buf,4096); //4096用于测试写入字节不大于4096时的原子性 if(real_wnum==-1) if(errno==EAGAIN) printf(\}

程序2:与程序1一起测试写FIFO的规则,第一个命令行参数是请求从FIFO读出的字节数

#include #include #include #include

#define FIFO_SERVER \

main(int argc,char** argv) { char r_buf[4096*2]; int fd; int r_size; int ret_size; r_size=atoi(argv[1]); printf(\ memset(r_buf,0,sizeof(r_buf)); fd=open(FIFO_SERVER,O_RDONLY|O_NONBLOCK,0); //fd=open(FIFO_SERVER,O_RDONLY,0); //在此处可以把读程序编译成两个不同版本:阻塞版本及非阻塞版本 if(fd==-1) { printf(\ exit(); } while(1) { memset(r_buf,0,sizeof(r_buf));

} ret_size=read(fd,r_buf,r_size); if(ret_size==-1) if(errno==EAGAIN) printf(\ printf(\ sleep(1); } pause(); unlink(FIFO_SERVER); 程序应用说明:

把读程序编译成两个不同版本:

? ?

阻塞读版本:br 以及非阻塞读版本nbr

把写程序编译成两个四个版本:

? ? ? ?

非阻塞且请求写的字节数大于PIPE_BUF版本:nbwg 非阻塞且请求写的字节数不大于PIPE_BUF版本:版本nbw 阻塞且请求写的字节数大于PIPE_BUF版本:bwg 阻塞且请求写的字节数不大于PIPE_BUF版本:版本bw

下面将使用br、nbr、w代替相应程序中的阻塞读、非阻塞读 验证阻塞写操作:

1. 当请求写入的数据量大于PIPE_BUF时的非原子性:

o nbr 1000 o bwg

2. 当请求写入的数据量不大于PIPE_BUF时的原子性:

o nbr 1000 o bw

验证非阻塞写操作:

1. 当请求写入的数据量大于PIPE_BUF时的非原子性:

o nbr 1000 o nbwg

2. 请求写入的数据量不大于PIPE_BUF时的原子性:

o nbr 1000 o nbw

不管写打开的阻塞标志是否设置,在请求写入的字节数大于4096时,都不保证写入的原子性。但二者有本质区别:

对于阻塞写来说,写操作在写满FIFO的空闲区域后,会一直等待,直到写完所有数据为止,请求写入的数据最终都会写入FIFO;

而非阻塞写则在写满FIFO的空闲区域后,就返回(实际写入的字节数),所以有些数据最终不能够写入。 对于读操作的验证则比较简单,不再讨论。 2.5有名管道应用实例

在验证了相应的读写规则后,应用实例似乎就没有必要了。 小结:

管道常用于两个方面:(1)在shell中时常会用到管道(作为输入输入的重定向),在这种应用方式下,管道的创建对于用户来说是透明的;(2)用于具有亲缘关系的进程间通信,用户自己创建管道,并完成读写操作。

FIFO可以说是管道的推广,克服了管道无名字的限制,使得无亲缘关系的进程同样可以采用先进先出的通信机制进行通信。

管道和FIFO的数据是字节流,应用程序之间必须事先确定特定的传输\协议\,采用传播具有特定意义的消息。

要灵活应用管道及FIFO,理解它们的读写规则是关键。 附1:kill -l 的运行结果,显示了当前系统支持的所有信号:

1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 32) SIGRTMIN 33) SIGRTMIN+1 34) SIGRTMIN+2 35) SIGRTMIN+3 36) SIGRTMIN+4 37) SIGRTMIN+5 38) SIGRTMIN+6 39) SIGRTMIN+7 40) SIGRTMIN+8 41) SIGRTMIN+9 42) SIGRTMIN+10 43) SIGRTMIN+11 44) SIGRTMIN+12 45) SIGRTMIN+13 46) SIGRTMIN+14 47) SIGRTMIN+15 48) SIGRTMAX-15 49) SIGRTMAX-14 50) SIGRTMAX-13 51) SIGRTMAX-12 52) SIGRTMAX-11 53) SIGRTMAX-10 54) SIGRTMAX-9 55) SIGRTMAX-8 56) SIGRTMAX-7 57) SIGRTMAX-6 58) SIGRTMAX-5 59) SIGRTMAX-4 60) SIGRTMAX-3 61) SIGRTMAX-2 62) SIGRTMAX-1 63) SIGRTMAX 除了在此处用来说明管道应用外,接下来的专题还要对这些信号分类讨论。 附2:对FIFO打开规则的验证(主要验证写打开对读打开的依赖性)

#include #include #include #include #define FIFO_SERVER \ int handle_client(char*); main(int argc,char** argv) { int r_rd; int w_fd; pid_t pid; if((mkfifo(FIFO_SERVER,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST)) printf(\ handle_client(FIFO_SERVER); } int handle_client(char* arg) { int ret; ret=w_open(arg); switch(ret) { case 0: { printf(\ printf(\ return -1; } case -1: { printf(\ENXIO\ return -1; } case 1: { printf(\ return 1; } default: { printf(\ return 0; } } unlink(FIFO_SERVER); } int w_open(char*arg) //0 open error for no reading //-1 open error for other reasons //1 open ok { if(open(arg,O_WRONLY|O_NONBLOCK,0)==-1) { if(errno==ENXIO) { return 0; } else return -1; } return 1; } 参考文献:

1. UNIX网络编程第二卷:进程间通信,作者:W.Richard Stevens,译者:杨继张,清华大学出版

社。丰富的UNIX进程间通信实例及分析,对Linux环境下的程序开发有极大的启发意义。 2. linux内核源代码情景分析(上、下),毛德操、胡希明著,浙江大学出版社,当要验证某个结

论、想法时,最好的参考资料;

3. UNIX环境高级编程,作者:W.Richard Stevens,译者:尤晋元等,机械工业出版社。具有丰富

的编程实例,以及关键函数伴随Unix的发展历程。

4. http://www.linux.org.tw/CLDP/gb/Secure-Programs-HOWTO/x346.html 点明linux下

sigaction的实现基础,linux源码../kernel/signal.c更说明了问题; 5. pipe手册,最直接而可靠的参考资料 6. fifo手册,最直接而可靠的参考资料


Linux环境进程间通信(一):管道及有名管道(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:国家高速公路网成渝地区环线乐山至雅安公路

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: