-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathchildsgame.c
166 lines (140 loc) · 5.11 KB
/
childsgame.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/* Write a C program to implement the following game.
The parent program P first creates two pipes and then spawns two child processes
C and D. One of the two pipes is meant for communication between P and C and the
other one for communication between P and D. Now a loop runs as follows.
In each iteration (also called a round), P first randomly chooses one of the
flags MIN or MAX. The choices randomly varies from one iteration to another.
Each of the two child processes C and D generates a random positive integer and
sends that to P via its pipe. P reads the two integers. Let these be c and d
respectively. If P has chosen MIN, then the child which sends the smaller of c
and d gets one point and if P has chosen MAX, then the child which sends the
larger of c and d gets one point. If c == d, then this round is ignored. The
child process which first obtains 10 points wins the game.
When the game ends, P sends a user-defined signal to both C and D and the child
processes exit after handling the signal (in order to know who was the winner).
After C and D exits, the parent process also exists. During each iteration of
the game, P should also print appropriate messages like P's choice of flag,
the integers received from C and D, which child gets the point, the current
scores of C and D in order to let the user know how the game is going on.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/types.h>
#define BUFSIZE 20
#define WINNING_CONDITION 10
static int stop = 0;
// Custom signal handler to handle the termination of game
void end_process(int sig) {
if (sig == SIGUSR1) {
stop = 1;
}
else if (sig == SIGUSR2) {
stop = 2;
}
}
int main() {
pid_t pid1, pid2;
// Create the pipe descriptors
int fd1[2], fd2[2];
pipe(fd1);
pipe(fd2);
// Assign the custom signal handler to SIGUSR1 signal
signal(SIGUSR1, end_process);
signal(SIGUSR2, end_process);
if ((pid1 = fork()) == 0) {
// Child 1
srand((unsigned int)time(NULL) ^ getpid());
close(fd1[0]); // Close the read end as the child will not read
// Generate a random number and place it on the pipe
while(!stop) {
int n = rand() % 100;
char line[BUFSIZE];
sprintf(line, "%d", n);
write(fd1[1], line, BUFSIZE);
}
// Handle the exit of the child process by displaying proper message
if (stop == 1) {
printf("C: I am the winner\n");
} else if (stop == 2) {
printf("C: D is the winner\n");
}
printf("Exiting from child C\n\n");
} else {
if ((pid2 = fork()) == 0) {
// Child 2
srand((unsigned int)time(NULL) ^ getpid());
close(fd2[0]); // Close the read end as the child will not read
// Generate a random number and place it on the pipe
while(!stop) {
int n = rand() % 100;
char line[BUFSIZE];
sprintf(line, "%d", n);
write(fd2[1], line, BUFSIZE);
}
// Handle the exit of the child process by displaying proper message
if (stop == 1) {
printf("D: C is the winner\n");
} else if (stop == 2) {
printf("D: I am the winner\n");
}
printf("Exiting from child D\n\n");
} else {
// Parent
close(fd1[1]);
close(fd2[1]); // Close the write ends as the parent will not read
srand((unsigned int)time(NULL) ^ getpid());
int round = 1;
int score1 = 0, score2 = 0;
char line[BUFSIZE];
char winner;
int num1, num2, choice;
while (1) {
printf("Round number: %d\n", round++);
choice = rand() % 2; // P chooses a flag: 0 for MAX and 1 for MIN
// Read and print the first integer from the pipe
read(fd1[0], line, BUFSIZE);
sscanf(line, "%d", &num1);
printf("Integer received from C: %d\n", num1);
// Read and print the second integer from the pipe
read(fd2[0], line, BUFSIZE);
sscanf(line, "%d", &num2);
printf("Integer received from D: %d\n", num2);
// Choose the winner for the round and add to its point
if (choice) {
printf("P's choice of flag: MIN\n");
} else {
printf("P's choice of flag: MAX\n");
}
if (num1 == num2)
printf("This round is a tie!\n");
else if ((num1 < num2 && choice) || (num1 > num2 && !choice)) {
printf("C gets the point\n");
score1++;
} else {
printf("D gets the point\n");
score2++;
}
printf("Updated scores: C = %d, D = %d\n\n", score1, score2);
// Break when score of any child becomes 10
if (score1 == WINNING_CONDITION || score2 == WINNING_CONDITION)
break;
}
// Send appropriate singal to the children to let them know who the winner was
if (score1 > score2) {
kill(pid1, SIGUSR1);
kill(pid2, SIGUSR1);
} else {
kill(pid1, SIGUSR2);
kill(pid2, SIGUSR2);
}
// Wait for the children to terminate and then terminate the parent
waitpid(pid1, &num1, 0);
waitpid(pid2, &num2, 0);
printf("Exiting from parent P\n");
}
}
return 0;
}