嵌入式Linux并发程序设计,进程间通信方式,有名管道,有名管道特点,有名管道创建mkfifo()

2019-07-13 08:32发布

文章目录

1,有名管道的特点

  1. 对应管道文件,可用于任意进程之间进行通信:有名管道创建好之后,在系统中有实际的文件和有名管道对应,任意两个进程可以通过路径和文件名指定同一个有名管道进行通信
  2. 打开管道时可指定读写方式:有名管道用open()打开的时候可以指定不同的读写方式,从而可以确定读端和写端
  3. 通过文件IO操作,内容存放在内存中:通过文件IO read()和write()进行操作。虽然有名管道有一个实际的文件被创建,在文件系统中可见,但是往管道中写入的所有内容实际上依然是存放在内存中的(跟无名管道一样),当所有的读端和写端都关闭的时候,管道存放在内存中的内容都会被释放
  4. 有名管道打开的时候有可能会阻塞。当只有读端或只有写端的时候,open()会阻塞,只有当读端和写端同时存在的时候,open()才会返回,程序才会继续执行。

2,有名管道的创建mkfifo()

#include
#include
int mkfifo(const char *path, mode_t mode);
  1. 成功时返回0,失败时返回EOF(如果创建的管道已经存在,创建就会失败)
  2. path 创建的管道文件路径
  3. mode 管道文件的权限,如0666(管道文件的权限主要是读写权限)

3,有名管道读写—示例

进程A:循环从键盘输入并写入有名管道myfifo,输入quit时退出
进程B:循环统计进程A每次写入myfifo的字符串的长度 /* create_fifo.c */ #include #include #include int main(int argc, const char *argv[]) { if(mkfifo("myfifo",0666) < 0) { perror("mkfifo"); exit(-1); } return 0; } /* write_fifo.c */ #include #include #include #include #define N 32 int main(int argc, const char *argv[]) { char buf[N]; int pfd; if((pfd = open("myfifo",O_WRONLY)) < 0) { perror("open"); exit(-1); } printf("write myfifo ");//进程打开管道后显示这一句 while(1) { printf("Please input a string (quite exit! "); fgets(buf,N,stdin); if(strcmp(buf,"quite ") == 0)break; write(pfd,buf,N); } close(pfd); return 0; } /* read_fifo.c */ #include #include #include #include #define N 32 int main(int argc, const char *argv[]) { char buf[N]; int pfd; if((pfd = open("myfifo",O_RDONLY)) < 0) { perror("open"); exit(-1); } printf("read myfifo ");//进程打开管道后显示这一句 while(read(pfd,buf,N) > 0)//写端存在,管道中没有数据的时候,读管道阻塞;写端不存在,管道中没有数据的时候,read()返回0 { printf("the length of string is %d ",strlen(buf)); } close(pfd); return 0; }
1,创建好三个c文件,并编译
linux@linux:~/test/stdio/fifo_sample$ ls fifo_create.c fifo_read.c fifo_write.c linux@linux:~/test/stdio/fifo_sample$ gcc fifo_create.c -o fifo_create.out linux@linux:~/test/stdio/fifo_sample$ gcc fifo_write.c -o fifo_write.out linux@linux:~/test/stdio/fifo_sample$ gcc fifo_read.c -o fifo_read.out linux@linux:~/test/stdio/fifo_sample$ ls fifo_create.c fifo_create.out fifo_read.c fifo_read.out fifo_write.c fifo_write.out
2,运行fifo_create.out,可以看到多了管道文件
linux@linux:~/test/stdio/fifo_sample$ ./fifo_create.out linux@linux:~/test/stdio/fifo_sample$ ll total 44 drwxrwxr-x 2 linux linux 4096 11月 12 11:13 ./ drwxrwxr-x 6 linux linux 4096 11月 12 01:01 ../ -rw-rw-r-- 1 linux linux 185 11月 12 10:13 fifo_create.c -rwxrwxr-x 1 linux linux 7418 11月 12 11:04 fifo_create.out* -rw-rw-r-- 1 linux linux 379 11月 12 11:03 fifo_read.c -rwxrwxr-x 1 linux linux 7647 11月 12 11:05 fifo_read.out* -rw-rw-r-- 1 linux linux 438 11月 12 11:03 fifo_write.c -rwxrwxr-x 1 linux linux 7681 11月 12 11:04 fifo_write.out* prw-rw-r-- 1 linux linux 0 11月 12 11:13 myfifo|
  • 可以看到管道文件大小是0,实际上管道文件大小永远是0,因为管道中的内容是保存在内存里的,而不是磁盘上
3,运行fifo_read.out或fifo_write.out,可以看到程序处于阻塞状态。以先运行fifo_read.out为例(先运行写管道也一样)
linux@linux:~/test/stdio/fifo_sample$ ./fifo_read.out linux@linux:~/test/stdio/fifo_sample$ ps -aux |grep fifo linux 3089 0.0 0.5 15196 6072 pts/10 S+ 10:49 0:01 vi fifo_read.c linux 3306 0.0 0.0 2024 280 pts/12 S+ 11:15 0:00 ./fifo_read.out linux 3314 0.0 0.0 6108 852 pts/0 S+ 11:18 0:00 grep --color=auto fifo
  1. 当进程打开一个有名管道的时候,如果当前只有读端或只有写端,open()会阻塞
    open()的下一条指令
    printf(“read myfifo ”);//进程打开管道后显示这一句
    没有执行
  2. 只有当读端和写端都存在是,两个进程中的open()才能正常执行
4,在另一个终端运行
读进程 写进程 linux@linux:~/test/stdio/fifo_sample$ ./fifo_read.out
write myfifo
linux@linux:~/test/stdio/fifo_sample$ ./fifo_write.out
write myfifo
Please input a string (quite exit! the length of string is 4
qwe
Please input a string (quite exit!
the length of string is 2
w
Please input a string (quite exit!
linux@linux:~/test/stdio/fifo_sample$
quite
linux@linux:~/test/stdio/fifo_sample$
  1. 运行fifo_write.out后,管道有了写端,读进程和写进程的open()才能正常运行,可以看到open()的下一条指令
    printf(“read myfifo ”);//进程打开管道后显示这一句
    printf(“write myfifo ”);//进程打开管道后显示这一句
    正常执行了
  2. 当写端输入quite时,写端不存在了,当写端不存在了,并且管道中没有数据数据,读管道会立刻返回0,返回0,就会退出循环,程序结束