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

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

进行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.\n");
exit(1);
}
if((mkfifo(FIFO2,0777)<0)&&(errno!=EEXIST))
{
printf("cannot create fifo.\n");
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!\n");
pd++;//平局
}
else
{
printf("%s wins!\n",(tmp>0)?"p1":"p2");
if(tmp>0)p1w++;//p1胜
else p2w++; //p2胜
}
}
//打印最终统计结果
printf("In summary:\n");
printf("p1 wins %d rounds.\n",p1w);
printf("p2 wins %d rounds.\n",p2w);
printf("%d rounds end in a draw.\n",pd);
printf("%s wins in the game!\n",(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;
}

结果:

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

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

  1. 共享内存+互斥量实现linux进程间通信 分类: Linux C/C++ 2015-03-26 17:14 67人阅读 评论(0) 收藏

    一.共享内存简介 共享内存是进程间通信中高效方便的方式之一.共享内存允许两个或更多进程访问同一块内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针,两个进程可以对一块共享 ...

  2. 09_编写脚本,实现人机<石头,剪刀,布>游戏

    #!/bin/bashgame=(石头 剪刀 布)num=$[RANDOM%3]computer=${game[$num]}#通过随机数获取计算机的出拳#出拳的可能性保存在一个数组中,game[0], ...

  3. Pygame:编写一个小游戏 标签: pythonpygame游戏 2017-06-20 15:06 103人阅读 评论(0)

    大学最后的考试终于结束了,迎来了暑假和大四的漫长的"自由"假期.当然要自己好好"玩玩"了. 我最近在学习Python,本意是在机器学习深度学习上使用Python ...

  4. 用Micro:bit做剪刀、石头、布游戏

    剪刀.石头.布游戏大家都玩过,今天我们用Micro:bit建一个剪刀.石头.布游戏! 第一步,起始 当你摇动它时,我们希望the micro:bit选择剪刀.石头.布.尝试创建一个on shake b ...

  5. c++下使用命名管道实现进程间通信

    前面已经使用邮槽实现过进程间通信:http://www.cnblogs.com/jzincnblogs/p/5192654.html ,这里使用命名管道实现进程间通信. 与邮槽不同的是,命名管道在进程 ...

  6. Python 石头 剪刀 布

    di = {1: '石头', 2: '剪刀', 3: '布'} def win(x, y): if len({x[0], y[0]}) == 1: print('平局.') else: if {x[0 ...

  7. 自己写的一个小的剪刀——石头——布游戏的GUI程序

    很简单的一个程序,建议各位初学Java的同学可以试试写写这个程序: import javax.swing.JOptionPane; public class Game { public static ...

  8. 用 Python 编写剪刀、石头、布的小游戏(快速学习python语句)

    import random#定义手势类型allList = ['石头','剪刀','布']#定义获胜的情况winList = [['石头','剪刀'],['剪刀','布'],['步','石头']]pr ...

  9. SQL Server 连接问题-命名管道

    原文:SQL Server 连接问题-命名管道 出自:http://blogs.msdn.com/b/apgcdsd/archive/2011/01/12/sql-server-1.aspx 一.前言 ...

随机推荐

  1. SharePoint 2013 调查问卷的使用方法

    SharePoint 2013 调查问卷的使用方法 1,介绍调查问卷的用法. 2.图形和全部结果. 3,控制用户仅仅能看到自己答案. 1.确认有权限,假设没有管理管理权限请向管理员申请. 站点&quo ...

  2. MySQL 当记录不存在时插入,当记录存在时更新

    第一种: 示例一:插入多条记录 假设有一个主键为 client_id 的 clients 表,可以使用下面的语句: INSERT INTO clients (client_id,client_name ...

  3. C#实现如何判断一个数组中是否有重复的元素 返回一个数组升序排列后的位置信息--C#程序举例 求生欲很强的数据库 别跟我谈EF抵抗并发,敢问你到底会不会用EntityFramework

    C#实现如何判断一个数组中是否有重复的元素   如何判断一个数组中是否有重复的元素 实现判断数组中是否包含有重复的元素方法 这里用C#代码给出实例 方法一:可以新建一个hashtable利用hasht ...

  4. 2015/12/29 eclipse应用 输出三角形

    public class Myfirst { public static void main(String[] args) { System.out.println("hello world ...

  5. nginx与apache 对比 apache是同步多进程模型,一个连接对应一个进程;nginx是异步的,多个连接(万级别)可以对应一个进程

    nginx与apache详细性能对比 http://m.blog.csdn.net/lengzijian/article/details/7699444 http://www.cnblogs.com/ ...

  6. XMU 1607 nc与点对距离 【线段树】

    1607: nc与点对距离 Time Limit: 5000 MS  Memory Limit: 512 MBSubmit: 60  Solved: 8[Submit][Status][Web Boa ...

  7. Serializable 接口与 Java 序列化与反序列化

    0. 序列化的意义 从内存到本地即为本地化或者在网络中进行传输,或叫序列化,持久化. 某 Java 类实现 Serializable 接口的目的是为了可持久化(简单理解为本地化),比如网络传输或本地存 ...

  8. P3239 [HNOI2015]亚瑟王 期望dp

    这个题一看就是期望dp,但是我有个问题,一个事件的期望等于他所有事件可能行乘权值的和吗...为什么我有天考试的时候就不对呢...求大佬解释一下. 至于这道题,f[i][j]代表前i个有j个发动技能,这 ...

  9. 关于python语言使用redis时,连接是否需要关闭的问题

    python操作完redis,需要关闭连接的吧,怎么关闭呢 1人赞 回复 君惜丶: redis-server会关闭空闲超时的连接redis.conf中可以设置超时时间:timeout 300 2017 ...

  10. 第十八周 Leetcode 72. Edit Distance(HARD) O(N^2)DP

    Leetcode72 看起来比较棘手的一道题(列DP方程还是要大胆猜想..) DP方程该怎么列呢? dp[i][j]表示字符串a[0....i-1]转化为b[0....j-1]的最少距离 转移方程分三 ...