有名管道_3
编程实现3人间相互通信
思路:需要防止打开管道时,陷入死锁。
总共需要建立3对管道,6个管道。每两个用户之间都有一对管道。一个用户有2个读端和2个写端。
:1 :2 :3
1-2 w 1-2 r 1-3 r
1-3 w 2-1 w 3-1 w
2-1 r 2-3 w 2-3 r
3-1 r 3-2 r 3-2 w
注意
此处每个用户,都是fork出2个子进程,总共3个进程。其中2个进程用于分别接收另外两个用户的消息,1个进程负责向其余两个用户发送消息。
不管fork出多少个进程,每个进程都要专注做自己的事情。此处每次fork出一个新进程,该进程都会拥有与父进程相同的4个文件描述符。我们只使用我们需要的那个,关闭其余3个不需要的。
再次强调,每个进程都要专注做自己的事情。
1.c
/************************************************************************* > File Name: 1.c > Author: KrisChou > Mail:zhoujx0219@163.com > Created Time: Fri 22 Aug 2014 08:29:12 PM CST ************************************************************************/ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> int main(int argc, char* argv[])//EXE 12 13 21 31 { if(mkfifo(argv[1],0666) == -1 || mkfifo(argv[2], 0666) == -1) { perror("mkfifo"); exit(1); } int fd_12, fd_13, fd_21, fd_31 ; char buf_123[1024],buf_21[1024],buf_31[1024]; fd_12 = open(argv[1], O_WRONLY); fd_13 = open(argv[2], O_WRONLY); fd_21 = open(argv[3], O_RDONLY); fd_31 = open(argv[4], O_RDONLY); printf("open sucess ! \n"); if(fork() == 0) //child1 recv from 2 { close(fd_12); close(fd_13); close(fd_31); while(memset(buf_21, 0, 1024), read(fd_21, buf_21, 1024) > 0) { printf("from 2: "); write(1, buf_21, strlen(buf_21)); } close(fd_21); exit(1); } if(fork() == 0)// child2 recv from 3 { close(fd_12); close(fd_13); close(fd_21); while(memset(buf_31, 0, 1024), read(fd_31, buf_31, 1024) > 0) { printf("from 3: "); write(1, buf_31, strlen(buf_31)); } close(fd_31); exit(1); } close(fd_21); close(fd_31); while(memset(buf_123, 0, 1024), fgets(buf_123, 1024, stdin) != NULL) { write(fd_12, buf_123, strlen(buf_123)); write(fd_13, buf_123, strlen(buf_123)); } close(fd_12); close(fd_13); wait(NULL); wait(NULL); unlink(argv[1]); unlink(argv[2]); return 0 ; }
2.c
/************************************************************************* > File Name: 1.c > Author: KrisChou > Mail:zhoujx0219@163.com > Created Time: Fri 22 Aug 2014 08:29:12 PM CST ************************************************************************/ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> int main(int argc, char* argv[])//EXE 12 21 23 32 { if(mkfifo(argv[2],0666) == -1 || mkfifo(argv[3], 0666) == -1) { perror("mkfifo"); exit(1); } int fd_12, fd_21, fd_23, fd_32 ; char buf_213[1024],buf_32[1024],buf_12[1024]; fd_12 = open(argv[1], O_RDONLY); fd_21 = open(argv[2], O_WRONLY); fd_23 = open(argv[3], O_WRONLY); fd_32 = open(argv[4], O_RDONLY); printf("open sucess ! \n"); if(fork() == 0) //child2 recv from 1 { close(fd_21); close(fd_23); close(fd_32); while(memset(buf_12, 0, 1024), read(fd_12, buf_12, 1024) > 0) { printf("from 1: "); write(1, buf_12, strlen(buf_12)); } close(fd_12); exit(1); } if(fork() == 0)// child2 recv from 3 { close(fd_12); close(fd_21); close(fd_23); while(memset(buf_32, 0, 1024), read(fd_32, buf_32, 1024) > 0) { printf("from 3: "); write(1, buf_32, strlen(buf_32)); } close(fd_32); exit(1); } close(fd_12); close(fd_32); while(memset(buf_213, 0, 1024), fgets(buf_213, 1024, stdin) != NULL) { write(fd_21, buf_213, strlen(buf_213)); write(fd_23, buf_213, strlen(buf_213)); } close(fd_21); close(fd_23); wait(NULL); wait(NULL); unlink(argv[2]); unlink(argv[3]); return 0 ; }
3.c
/************************************************************************* > File Name: 1.c > Author: KrisChou > Mail:zhoujx0219@163.com > Created Time: Fri 22 Aug 2014 08:29:12 PM CST ************************************************************************/ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> int main(int argc, char* argv[])//EXE 13 31 23 32 { if(mkfifo(argv[2],0666) == -1 || mkfifo(argv[4], 0666) == -1) { perror("mkfifo"); exit(1); } int fd_13, fd_31, fd_23, fd_32 ; char buf_312[1024],buf_13[1024],buf_23[1024]; fd_13 = open(argv[1], O_RDONLY); fd_31 = open(argv[2], O_WRONLY); fd_23 = open(argv[3], O_RDONLY); fd_32 = open(argv[4], O_WRONLY); printf("open sucess ! \n"); if(fork() == 0) //child1 recv from 1 { close(fd_31); close(fd_23); close(fd_32); while(memset(buf_13, 0, 1024), read(fd_13, buf_13, 1024) > 0) { printf("from 1: "); write(1, buf_13, strlen(buf_13)); } close(fd_13); exit(1); } if(fork() == 0)// child2 recv from 2 { close(fd_13); close(fd_31); close(fd_32); while(memset(buf_23, 0, 1024), read(fd_23, buf_23, 1024) > 0) { printf("from 2: "); write(1, buf_23, strlen(buf_23)); } close(fd_23); exit(1); } close(fd_13); close(fd_23); while(memset(buf_312, 0, 1024), fgets(buf_312, 1024, stdin) != NULL) { write(fd_31, buf_312, strlen(buf_312)); write(fd_32, buf_312, strlen(buf_312)); } close(fd_31); close(fd_32); wait(NULL); wait(NULL); unlink(argv[2]); unlink(argv[4]); return 0 ; }
运行,分别打开3个终端,分别输入:
./1.exe 12.fifo 13.fifo 21.fifo 31.fifo ./2.exe 12.fifo 21.fifo 23.fifo 32.fifo ./3.exe 13.fifo 31.fifo 23.fifo 32.fifo