下面这个程序利用命名管道实现进程间通信,模拟石头剪刀布游戏。
主进程为裁判进程,两个子进程为选手进程。裁判与选手间各建立一个命名管道。
进行100次出招,最后给出游戏胜负。
#include <unistd.h> #include<fcntl.h> #include<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<errno.h> #include<stdlib.h> #include<string.h> #define FIFO1 "/tmp/myfifo1" #define FIFO2 "/tmp/myfifo2" #define SIZE 5 #define COUNT 100 int judge(char a,char b); int main(void) { int fp,fp1,fp2,i=1; int status; int nread; char buf[SIZE]={0}; char c1[COUNT]={0};//用来存放p1发送的消息 char c2[COUNT]={0};//用来存放p2发送的消息 pid_t p1 = fork(); //产生子进程p1 /*********************************/ if(p1==0) { srand(time(NULL)); while((fp=open(FIFO1,O_WRONLY|O_NONBLOCK))==-1);//只写打开管道1,不断尝试直到成功 for(;i<=100;i++) { sprintf(buf,"%d",rand()%3);//随机产生0-2的数字写入管道 while(write(fp,buf,SIZE)==-1);//不断尝试写直至成功 } close(fp); return 0; } /*********************************/ pid_t p2=fork(); //产生子进程p2,程序结构同p1 /*********************************/ if(p2==0) { srand(time(NULL)+100); while((fp=open(FIFO2,O_WRONLY|O_NONBLOCK))==-1); for(;i<=100;i++) { sprintf(buf,"%d",rand()%3); while(write(fp,buf,SIZE)==-1); } close(fp); exit(0); } /**************************************/ //创建2个管道 if((mkfifo(FIFO1,0777)<0)&&(errno!=EEXIST)) { printf("cannot create fifo. "); exit(1); } if((mkfifo(FIFO2,0777)<0)&&(errno!=EEXIST)) { printf("cannot create fifo. "); exit(2); } memset(buf,0,sizeof(buf));//清空缓冲区 //只读方式打开两个命名管道 while((fp1=open(FIFO1,O_RDONLY|O_NONBLOCK,0))==-1); while((fp2=open(FIFO2,O_RDONLY|O_NONBLOCK,0))==-1); sleep(3);//等待两个子进程中打开管道写端并输入数据,必要 for(;i<=100;i++)//连续读取100个数据 { nread=read(fp1,buf,SIZE); if(nread!=-1&&nread!=0) { c1[i]=buf[0];//结果存放至c1 } } i=1; for(;i<=100;i++) { nread=read(fp2,buf,SIZE); if(nread!=-1&&nread!=0) { c2[i]=buf[0];//结果存放至c2 } } int j=1; int p1w=0,p2w=0,pd=0; for(;j<=100;j++) { int tmp=judge(c1[j],c2[j]); printf("round %d:",j); if(tmp==0) { printf("in a draw! "); pd++;//平局 } else { printf("%s wins! ",(tmp>0)?"p1":"p2"); if(tmp>0)p1w++;//p1胜 else p2w++; //p2胜 } } //打印最终统计结果 printf("In summary: "); printf("p1 wins %d rounds. ",p1w); printf("p2 wins %d rounds. ",p2w); printf("%d rounds end in a draw. ",pd); printf("%s wins in the game! ",(p1w>p2w)?"p1":"p2"); //等待两个子进程结束 if(waitpid(p1,&status,0) < 0) { perror("waitpid"); exit(5); } if(waitpid(p2,&status,0)< 0) { perror("waitpid"); exit(6); } exit(0); } //0——石头,1——剪刀,2——布 int judge(char a,char b)//规定游戏判定规则 { int r=0; if(a==b) r=0; else { if(a=='0'&&b=='1')r=1; if(a=='0'&&b=='2')r=-1; if(a=='1'&&b=='2')r=1; if(a=='1'&&b=='0')r=-1; if(a=='2'&&b=='0')r=1; if(a=='2'&&b=='1')r=-1; } return r; }
结果:
版权声明:本文为博主原创文章,未经博主允许不得转载。