linux 管道实现进程间通信
通过使用管道可以在同一台计算机的不同进程间进行通信。管道类似一种文件,A进程与B进程通信,A向管道写入数据,B从管道读取数据。B要是与A进行通信同理,但最好要新建力一个管道文件。
对于管道通过open方式打开。但是通过open打开管道与打开普通文件是有区别的。
open(const char *filename,int open_flag);
open_flag的模式不同,打开的阻塞方式也不一样。
open(const char *filename,O_RDONLY);
通过只读方式打开管道,程序将在open调用处阻塞,直到有进程以写的方式打开同一个FIFO管道,否则程序一直阻塞。
open(const char *filename,O_RDONLY|O_NONBLOCK);
这种情况下就是没有其它进程以写的方式打开同一个管道,程序不会阻塞而是立即返回。
open(const char *filename,O_WRONLY);
通过只写方式打开管道,程序将在open调用处阻塞,直到有进程以读的方式打开同一个FIFO管道,否则程序一直阻塞。
open(const char *filename,O_WRONLY|O_NONBLOCK);
这种情况下就是没有其它进程以读的方式打开同一个管道,程序不会阻塞而是立即返回。
access函数的原型如下:
int access(const char *pathname, int mode);
此函数是用来获得调用进程对pathname所指向的文件(regular)或者是目录(directory)的访问权限。
pathname: 文件或者是目录路径
mode:访问模式。可以F_OK,F_OK,表示pathname所指向文件是否存在。
两个进程,一个进程A向命名FIFO管道写入数据,另一个进程通过同一个命名FIFO管道读入数据。
写入进程
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <limits.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> //管道名字 #define FIFO_NAME "/home/administrator/桌面/Java/pipe/pipefile" //管道每次写入的大小 #define BUFF_SIZE PIPE_BUF //一共写入多少数据 #define TEN_MEG (1024 * 1024 * 10) int main() { int pipe_id; int res; //以写入方式打开,在open处阻塞,直到有读入操作 int open_mode = O_WRONLY; int byte_sent = 0; char buffer[BUFF_SIZE + 1]; //判断文件是否存在 if(access(FIFO_NAME,F_OK) == -1) { //建立管道文件 res = mkfifo(FIFO_NAME,0777); if(0 != res) { printf("can not create fifo info\n"); exit(-1); } } printf("Process %d opening FIFO \n",getpid()); //打开管道文件,通过写入的方式,并阻塞,等待 //其它读入进程打开同一管道 pipe_id = open(FIFO_NAME,open_mode); if(-1 != pipe_id) { while(byte_sent < TEN_MEG) { //向管道写入数据 res = write(pipe_id,buffer,BUFF_SIZE); if(-1 == res) { printf("write to pipe error\n"); exit(-1); } printf("Process %d write %d byte size \n",getpid(),byte_sent); byte_sent = byte_sent + res; } } else { printf("can not open fifo file\n"); exit(-1); } printf("Process %d finish \n",getpid()); close(pipe_id); }
读进程
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <limits.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> //管道文件 #define FIFO_NAME "/home/administrator/桌面/Java/pipe/pipefile" #define BUFF_SIZE PIPE_BUF int main() { int pipe_id; int res; //通过只读方式打开,在open处阻塞,直到有写入进程 //打开同一管道 int open_mode = O_RDONLY; int byte_read = 0; char buffer[BUFF_SIZE + 1]; memset(buffer,‘\0‘,sizeof(buffer)); printf("Process %d opening FIFO \n",getpid()); //open处阻塞,直到有其它写入进程打开管道,解除阻塞 pipe_id = open(FIFO_NAME,open_mode); if(-1 != pipe_id) { do {//读取管道数据 res = read(pipe_id,buffer,BUFF_SIZE); byte_read = byte_read + res; }while(res > 0); } else { printf("can not open fifo file\n"); exit(-1); } close(pipe_id); printf("it is total read %d byte from pipe\n",byte_read); exit(0); }
写入进程
Process 3742 write 10424320 byte size
Process 3742 write 10428416 byte size
Process 3742 write 10432512 byte size
Process 3742 write 10436608 byte size
Process 3742 write 10440704 byte size
Process 3742 write 10444800 byte size
Process 3742 write 10448896 byte size
Process 3742 write 10452992 byte size
Process 3742 write 10457088 byte size
Process 3742 write 10461184 byte size
Process 3742 write 10465280 byte size
Process 3742 write 10469376 byte size
Process 3742 write 10473472 byte size
Process 3742 write 10477568 byte size
Process 3742 write 10481664 byte size
Process 3742 finish
administrator@ubuntu:~/桌面/Java/pipe$ ^C
读入进程
administrator@ubuntu:~/桌面/Java/pipe$ g++ pipewrite.cpp -o pipewrite
administrator@ubuntu:~/桌面/Java/pipe$ ./piperead
Process 3514 opening FIFO
it is total read 10485760 byte from pipe
administrator@ubuntu:~/桌面/Java/pipe$ ./piperead
Process 3741 opening FIFO
it is total read 10485760 byte from pipe
administrator@ubuntu:~/桌面/Java/pipe$
本文出自 “风清扬song” 博客,请务必保留此出处http://2309998.blog.51cto.com/2299998/1394828
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。