有名管道
无名管道和有名管道:
1. 管道是特殊类型的文件,在满足先入先出的原则写可以读写,不能定位读写位置。
2.管道是单向的。
3.无名管道阻塞于读写位置,而有名管道阻塞在创建位置。
4.无名管道一般只用于亲缘关系进程间通信;有名管道以磁盘文件的方式存在,可以实现本机任意两进程间通信。
shell创建有名管道
mknod 管道名 p //创建名为PIPETEST的有名管道 mknod为命令 p是参数,表示有名管道
指令 > 管道名 & //将指令结果输入到到管道文件中
指令 < 管道名 //以指定管道名中的内容做为输入
编程实现有名管道
int mkfifo (__const char *__path, __mode_t __mode):建立的有名管道文件必须之前不存在, mode是该文件的权限。成功返回0,否则返回-1.
通过read(), write()实现读写操作。
其阻塞方式见下图(我懒得打字了,就上图吧....)
例子:
写进程
#include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<fcntl.h> #include<string.h> #include<stdlib.h> #include<errno.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("Process %d finished\n", getpid()); exit(EXIT_SUCCESS); }
读进程
#include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<fcntl.h> #include<string.h> #include<stdlib.h> #include<errno.h> #include<sys/stat.h> #define FIFO_NAME "/tmp/my_fifo" //要创建的有名管道的路径 int main(int argc, char * argv[]) { int pipe_fd; int res; char buffer[4096]; int bytes_read = 0; memset(buffer, ‘\0‘, sizeof(buffer)); printf("Process %d opening FIFO O_RDONLY\n", getpid()); pipe_fd = open(FIFO_NAME, O_RDONLY); //打开有名管道 printf("the file‘s 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); }
运行时,先在一个终端运行写进程,此时写进程会阻塞。
用ctrl+alt+[F1-F6]切换终端,在新终端运行读进程。
读进程端结果为
再切换回原终端,写进程也执行完毕。
时间: 2024-10-22 23:30:57