命名管道实现进程间通信--石头、剪刀、布游戏 分类: linux 2014-06-01 22:50 467人阅读 评论(0) 收藏

下面这个程序利用命名管道实现进程间通信,模拟石头剪刀布游戏。

主进程为裁判进程,两个子进程为选手进程。裁判与选手间各建立一个命名管道。

进行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;
}




结果:

版权声明:本文为博主原创文章,未经博主允许不得转载。

原文地址:https://www.cnblogs.com/luo-peng/p/4646266.html