栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

实验二、进程间通信

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

实验二、进程间通信

实验二、进程间通信

进程间通信
    • 实验环境:
    • 实验时间:
    • 实验目的:
    • 实验目标:
    • 实验步骤:
    • 实验报告:
      • 实验步骤 1 的数据结构:
      • 实验步骤 1 的大小规则:
      • 实验步骤 2 的结构:
      • 实验步骤 3 中,你所选择的 IPC 方法:
      • 实验步骤 3,为何选择该方法?
      • 实验步骤 3,如果选择消息队列机制,描述消息缓冲区结构:
      • 实验步骤 4,如何创建 IPC 资源?
      • 实验步骤 5,程序主要流程或关键算法
      • 实验步骤 6,程序主要流程或关键算法:

实验环境:

Linux 平台

实验时间:

6 小时

实验目的:

初步了解 Linux 系统中,进程间通信的方法。

实验目标:

编写一个程序,用 Linux 中的 IPC 机制,完成两个进程“石头、剪子、布”的
游戏

实验步骤:

本实验可以创建三个进程,其中,一个进程为裁判进程,另外两个进程为选
手进程。可以将“石头、剪子、布”这三招定义为三个整型值。胜负关系:石头〉
剪子〉布〉石头。
选手进程按照某种策略(例如,随机产生)出招,交给裁判进程判断大小。
裁判进程将对手的出招和胜负结果通知选手。比赛可以采取多盘(>100盘)
定胜负,由裁判宣布最后结果。每次出招由裁判限定时间,超时判负。
每盘结果可以存放在文件或其他数据结构中。比赛结束,可以打印每盘的胜
负情况和总的结果。
1.设计表示“石头、剪子、布”的数据结构,以及它们之间的大小规则。
2.设计比赛结果的存放方式。
3.选择 IPC 的方法。
4.根据你所选择的 IPC 方法,创建对应的 IPC 资源。
5.完成选手进程。
6.完成裁判进程

实验报告: 实验步骤 1 的数据结构:

使用char* apt[] 形式来存储“石头、剪子、布”
具体的形式为 char* apt[] = {“rock”, “scissors”, “papper”};
索引 0 1 2 分别代表 石头、剪刀、布

实验步骤 1 的大小规则:

规则:石头 > 剪子 > 布 > 石头

实验步骤 2 的结构:

比赛结果的存放方式:

1、使用 0 1 2 表示每个选手的出招,使用两个 int [] 数组来存放选手的出招结果
2、使用 0 1 2 表示出招结果的比较,player_01和player_02平手的话就用 0 表示,player_01胜利就用 1 表示,player_02胜利就用 2 表示
也用一个 int [] 数组 来存放结果

实验步骤 3 中,你所选择的 IPC 方法:

选择消息队列的方式进行进程间通信

实验步骤 3,为何选择该方法?

使用消息队列不需要加锁,并且不局限于父子进程之间的通信,还可以实现双向通信。对于这个实验来说,正好符合选手和裁判之间的通信问题。

实验步骤 3,如果选择消息队列机制,描述消息缓冲区结构:

缓冲区的结构使用一个结构体来定义,但是它必须有一个消息类型,缓冲区的其他信息可以根据具体要求定义。

实验步骤 4,如何创建 IPC 资源?

创建消息队列可以使用 msgget()方法,该方法需要添加头文件 #include和#include
使用msgget()方法创建一个消息队列:
queue_id = msgget(QUEUE_ID, IPC_CREAT | IPC_EXCL | 0600);

实验步骤 5,程序主要流程或关键算法

主要流程:

关键算法:

裁判算法:

#include
#include
#include
#include
#include
#include

struct msgbuf {                                         //消息缓冲区,具体看 play_01.c
	long msgtype;
	int rps;
	int limit_time;
};



int result[105];                       //save the result of player_01 and player_02
int player_01_info[105];       //save the player_01 information
int player_02_info[105];       // 能用数组尽量用,用结构体的话,可能会出现内存错误

int main () {
	char *apt[] = {
		"rock",
		"scissors",
		"papper"
	};

	
	
	key_t key_01 = ftok(".", 21);
	key_t key_02 = ftok(".", 22);
	int Msg_ID_01 = msgget(key_01, IPC_CREAT|0777);
	int Msg_ID_02 = msgget(key_02, IPC_CREAT|0777);
	struct msgbuf Snd_Buf_01 = {1,-1, 1};
	struct msgbuf Rcv_Buf_01;
	struct msgbuf Snd_Buf_02 = {2,-1, 1};
	struct msgbuf Rcv_Buf_02;
	int count_0 = 0;     // the two players are all win
	int count_1 = 0;    // player_01 win
	int count_2 = 0;
	int index = 0;       // The index of wfo
	



	while (index < 101) {
		int nsend_01 = msgsnd(Msg_ID_01, &Snd_Buf_01, sizeof(Snd_Buf_01)- sizeof(long),0);
		
		int nread_01 = msgrcv(Msg_ID_01, &Rcv_Buf_01, sizeof(Rcv_Buf_01)-sizeof(long), 521, 0);
		
		int nsend_02 = msgsnd(Msg_ID_02, &Snd_Buf_02, sizeof(Snd_Buf_02)-sizeof(long), 0);
		
		int nread_02 = msgrcv(Msg_ID_02, &Rcv_Buf_02, sizeof(Rcv_Buf_02) - sizeof(long), 522, 0);
		
		int player_01_rps = Rcv_Buf_01.rps;  // player_01 result
		int player_02_rps = Rcv_Buf_02.rps;
		int cha = player_01_rps - player_02_rps;
		
		
		int temp;
		if (cha == 0){         // ping ju 
			temp = 0;
			count_0++;
		}
		else if (cha == -1 || cha == 2) {     // player_01 win the game
			temp = 1;
			count_1++;
		}
		else {
			temp = 2;
			count_2++;
		
		}
		int info1 = player_01_rps;
		int info2 = player_02_rps;
		
		result[index] = temp;
		player_01_info[index] = info1;
		player_02_info[index] = info2;
		index++;
		

	}
	printf("the result of the match is below:n");
	int ret1 = msgctl(Msg_ID_01, IPC_RMID, NULL);
	int ret2 = msgctl(Msg_ID_02, IPC_RMID, NULL);
	if (ret1 == -1 || ret2 == -1) {
		printf("fail to destory the msgqueuen");
	}
	for (int i = 0; i < index; i++) {
		int w = result[i];
		char* win;
		if (w == 0) {
			win = "deuce";
		}
		else if(w == 1) {
			win = "player_01";
		}
		else {
			win = "player_02";
		}
		
		int p1 = player_01_info[i];
		int p2 = player_02_info[i];

		char* player_01 = apt[p1];
		char* player_02 = apt[p2];
		printf("winner: %s, player_01: %s, player_02: %sn", win, player_01, player_02);
		printf("---------------------------------------------------n");
	}
	printf("the num of deuce is: %dn", count_0);
	printf("the num of player_01 is win: %dn", count_1);
	printf("the num of player_02 is win: %dn", count_2);
	if (count_1 == count_2) {
		printf("they are deucing!n");
	}
	else if (count_1 < count_2) {
		printf("the winner is player_02n");
	}
	else {
		printf("the winner is player_01n");
	}
	return 0;
}

实验步骤 6,程序主要流程或关键算法:

两个选手的代码算法:
选手1:

#include
#include
#include
#include
#include
#include
#include



struct msgbuf {                                          
	long msgtype;                         
	int rps;                                    
	int limit_time;
};

int main () {
	struct msgbuf Snd_Buf = {521, -1, 0};             // 发送消息类型为 521 到消息队列
	struct msgbuf Rcv_Buf;
	key_t key = ftok(".", 21);                                  // key 与 裁判程序里面的一样
	int Msg_ID = msgget(key, IPC_CREAT|0777);
	if (Msg_ID == -1) {
		printf("Msg create failure!n");
	}
	int index = 0;
	srand(time(NULL));
	while (index < 101) {
		int nread = msgrcv(Msg_ID, &Rcv_Buf, sizeof(Rcv_Buf) - sizeof(long), 1, 0);    
		// 这个函数 的 sizeof(Rcv_Buf) - sizeof(long)很重要
			
		int rps_01 = rand()%3;
		Snd_Buf.rps = rps_01;
		int nsnd = msgsnd(Msg_ID, &Snd_Buf, sizeof(Snd_Buf) - sizeof(long), 0);
		
		index++;
	}	
	return 0;
}

选手2:

#include
#include
#include
#include
#include
#include
#include

struct msgbuf {
	long msgtype;
	int rps;
	int limit_time;
};

int main () {
	struct msgbuf Snd_Buf = {522, -1, 0};
	struct msgbuf Rcv_Buf;
	key_t key = ftok(".", 22);
	int Msg_ID = msgget(key, IPC_CREAT|0777);
	if (Msg_ID == -1) {
		printf("Msg create failure!n");
	}
	int index = 0;
	srand(time(NULL));
	while (index < 101) {
		int nread = msgrcv(Msg_ID, &Rcv_Buf, sizeof(Rcv_Buf) - sizeof(long), 2, 0);
			
		int rps_02 = rand()%3;
		Snd_Buf.rps = rps_02;
		int nsnd = msgsnd(Msg_ID, &Snd_Buf, sizeof(Snd_Buf) - sizeof(long), 0);
		
		index++;
	}	
	return 0;
}

实验部分结果的展示:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/334127.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号