Experiment 2, inter-process communication

Experiment 2, inter-process communication

lab environment:

Linux platform

Experiment time:

6 hours

Purpose:

Have a preliminary understanding of the method of inter-process communication in the Linux system.

Experimental goals:

Write a program to use the IPC mechanism in Linux to complete the two-process "rock, scissors, cloth"
game

Experimental steps:

This experiment can create three processes, one of which is the referee process, and the other two are player
processes. The three tricks of "rock, scissors, and cloth" can be defined as three integer values. Winning relationship: rock >
scissors > cloth > rock.
Players process moves according to a certain strategy (for example, randomly generated), and hand them over to the referee process to judge the size.
The referee process notifies the players of the opponent's move and the result of the outcome. The game can take multiple rounds (>100 rounds)
to decide the outcome, and the referee will announce the final result. The time for each move is limited by the referee, and the timeout will be judged as a loss.
The per-disk results can be stored in files or other data structures. At the end of the game, the winning and losing situation of each set
and the total result can be printed.
1. Design a data structure representing "rock, paper, scissors" and the size rules between them.
2. Design the way to store the results of the competition.
3. Select the method of IPC.
4. Create corresponding IPC resources according to the IPC method you choose.
5. Complete the player process.
6. Complete the referee process

experimental report:

Data structure of experiment step 1:

Use the form of char* apt[] to store "rock, scissors, cloth" The
specific form is char* apt[] = {"rock", "scissors", "papper"};
index 0 1 2 represent rock, scissors, cloth

insert image description here

Size rules for Experimental Step 1:

Rule: rock > scissors > cloth > rock

Structure of Experiment Step 2:

How to save the game results:

1. Use 0 1 2 to represent the move of each player, and use two int [] arrays to store the result of the player's move
2. Use 0 1 2 to represent the comparison of the result of the move. If player_01 and player_02 are tied, use 0 to represent , player_01 wins with 1, player_02 wins with 2 and
also uses an int [] array to store the result

insert image description here

In lab step 3, the IPC method you choose:

Choose the way of message queue for inter-process communication

Experimental step 3, why choose this method?

The use of message queues does not require locking, and is not limited to communication between parent and child processes, but also enables two-way communication. For this experiment, the problem of communication between the players and the referee fits perfectly.

Experimental step 3, if you choose the message queue mechanism, describe the message buffer structure:

The structure of the buffer is defined by a structure, but it must have a message type, and other information of the buffer can be defined according to specific requirements.

insert image description here

Experiment step 4, how to create an IPC resource?

To create a message queue, you can use the msgget() method, which needs to add header files #include<sys/ipc.h> and #include<sys/msg.h>
Use the msgget() method to create a message queue:
queue_id = msgget(QUEUE_ID , IPC_CREAT | IPC_EXCL | 0600);

insert image description here

Experimental step 5, the main process or key algorithm of the program

Main process:

insert image description here

Key algorithm:

Referee Algorithm:

#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<string.h>

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
	
/*

	msgsnd() msgrcv() 两个函数最重要的是第三个参数 sizeof(Buf) - sizeof(msgtype)
*/


	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 msgqueue\n");
	}
	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: %s\n", win, player_01, player_02);
		printf("---------------------------------------------------\n");
	}
	printf("the num of deuce is: %d\n", count_0);
	printf("the num of player_01 is win: %d\n", count_1);
	printf("the num of player_02 is win: %d\n", count_2);
	if (count_1 == count_2) {
    
    
		printf("they are deucing!\n");
	}
	else if (count_1 < count_2) {
    
    
		printf("the winner is player_02\n");
	}
	else {
    
    
		printf("the winner is player_01\n");
	}
	return 0;
}

Experimental step 6, the main process or key algorithm of the program:

Code algorithm for two players:
Player 1:

#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>


/*
	消息缓冲区的定义
	long msgtype;     消息类型
	int rps;                  代表石头剪刀布  0  1  2
	int limit_time;       裁判发来的出招限制时间,但是我没用 嘿嘿
*/
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;
}

Player 2:

#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>

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

The display of the results of the experimental part:

insert image description here

Guess you like

Origin blog.csdn.net/weixin_45788387/article/details/120815371