有名管道 FIFO
一个进程以读方式打开,另一个以写方式打开才能正常运行只打开一端将阻塞。
无名管道是临时的,在完成通信后将自动消失,且只能在具有亲缘关系的进程间实现通信,有名管道FIFO有效地客服了这一个问题。有名管道是一个存在的特殊文件,可以在不同进程间通信,用户可以通过shell来创建有名管道(mknod 命令)。
命令管道的重用操作如下所示:
C++ Code
1 2 3 4 5 6 7 | | int mkfifo(_const char *_path, _mode_t _mode) // mode:如0766 fd open(const char *pathname, flages) //flages: O_RDONLY, O_WRONLY, or O_RDWR. int read(int _fd, void *_buf, size_t _nbytes) int write(int _fd, void *_buf, size_t _nbytes) |
下面是一个非亲缘关系进程使用有名管道通信应用实例。
写进程将要发送的数据发送到有名管道,读进程从有名管道中读取发送端发送的数据,在此过程中,只使用了一个有名管道,因此,读写是单向的,即只能从写进程读进程发送数据,如果要实现双向数据传输,则需要再使用一个有名管道。
向命名管道中发送数据的进程源代码如下所示:
C++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | | #include<unistd.h> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<fcntl.h> #include<limits.h> #include<sys/types.h> #include<sys/stat.h>
#define FIFO_NAME "/tmp/my_fifo" //命名管道位置
int main(int argc, char *argv[]) { int pipe_fd; int res; char buffer[] = "hello world!"; if(access(FIFO_NAME, F_OK) == -1) //文件是否存在 { res = mkfifo(FIFO_NAME, 0766); //创建文件 if(res != 0) { fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME); exit(EXIT_FAILURE); }
} printf("Process %d opening FIFO O_WRONLY\n", getpid()); pipe_fd = open(FIFO_NAME, O_WRONLY); //打开有名管道 printf("the file's descriptor is %d \n", pipe_fd); if(pipe_fd != -1) { res = write(pipe_fd, buffer, sizeof(buffer)); //写数据 if(res == -1) { fprintf(stderr, "Write error on pipe\n"); exit(EXIT_FAILURE); } printf("write data is %s ,%d bytes is write\n", buffer, res); close(pipe_fd); //关闭管道 } else { exit(EXIT_FAILURE); } printf("Procecss %d finished\n", getpid()); exit(EXIT_SUCCESS);
} |
读进程负责从有名管道中读取数据,其源代码如下所示:
C++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | | #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> #include<fcntl.h> #include<limits.h> #include<sys/stat.h> #include<sys/types.h>
#define FIFO_NAME "/tmp/my_fifo"
int main(int argv, char *argc[]) { int pipe_fd; int res; char buffer[4096]; int bytes_read = 0; memset(buffer, '\0', sizeof(buffer)); printf("Process %d opening FIFO O_RDONLY", getpid()); pipe_fd = open(FIFO_NAME, O_RDONLY); //打开管道,因为创建在写进程,故执行时需要先执行写进程。 printf("the files descriptor is %d \n", pipe_fd); if(pipe_fd != -1) { bytes_read = read(pipe_fd, buffer, sizeof(buffer)); //读出数据 printf("the read data is %s \n", buffer); close(pipe_fd); //关闭管道 } else exit(EXIT_FAILURE); printf("Process %d finished, %d bytes read\n", getpid(), bytes_read); exit(EXIT_SUCCESS); } |