-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
152 lines (121 loc) · 5.12 KB
/
main.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
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#define BUFFER_SIZE 128
#define READ_END 0
#define WRITE_END 1
int main() {
// open OUTPUT file
FILE* fp;
fp = fopen("output.txt", "w");
char write_msg[BUFFER_SIZE] = "I'm a chlid.";
char read_msg[BUFFER_SIZE];
char buffer[BUFFER_SIZE];
pid_t pid, waitPid; // child process id
int fd[5][2]; // file descriptors for the pipe
int i, status = 0, totalRandomTime = 0;
int startTime, finishTime, finishTimeMsec;
int result, nread; // used for 5th child
fd_set inputs, inputfds; // sets of fildes
FD_ZERO(&inputs); // init inputs to empty set
FD_SET(0, &inputs); // sets fildes 0 (stdin)
// get the time
struct timeval tv;
// Fork five children processes.
for (i = 0; i < 5; i++) {
// Create the pipe.
if (pipe(fd[i]) == -1) {
fprintf(stderr,"pipe() failed");
return 1;
}
// Fork a child process.
pid = fork();
if (pid > 0) {
// PARENT PROCESS.
gettimeofday(&tv, NULL);
int timeSec = (int) tv.tv_sec;
// the parent need to wait for each child process to finish
// while ((waitPid = wait(&status)) > 0);
// Close the unused WRITE end of the pipe.
close(fd[i][WRITE_END]);
for (int j = 0; j < 5; j++) {
inputfds = inputs;
// using SELECT
result = select(5, &inputfds, (fd_set*) 0, NULL, NULL);
if (FD_ISSET(fd[j][READ_END], &inputfds)) {
ioctl(fd[j][READ_END], FIONREAD, &nread);
}
nread = read(fd[j][READ_END], read_msg, strlen(write_msg)+1);
read_msg[nread] = 0;
gettimeofday(&tv, NULL);
int currTimeSec = (int) tv.tv_sec;
int currTimeMsec = (int) ((tv.tv_usec) / 1000);
// write directly to OUTPUT file
fprintf(fp, "0:%2d.%d: Parent: Read '%s' from the pipe. PID: %d\n", currTimeSec - timeSec, currTimeMsec, read_msg, getppid());
}
// Close the READ end of the pipe.
close(fd[i][READ_END]);
break;
}
else if (pid == 0) {
// CHILD PROCESS.
gettimeofday(&tv, NULL);
startTime = (int) tv.tv_sec;
if (i < 4) {
// Close the unused READ end of the pipe.
close(fd[i][READ_END]);
for (;;) {
gettimeofday(&tv, NULL);
finishTime = (int) tv.tv_sec;
finishTimeMsec = (int) ((tv.tv_usec) / 1000);
sprintf(write_msg, "0:%2d.%d: Child %d (PID=%d): I'm a child.\n", finishTime - startTime, finishTimeMsec, i + 1, getpid());
printf("%s", write_msg);
// random 0 1 2s
srand(time(NULL));
int randomNum = rand() % 3;
// Write from the WRITE end of the pipe.
write(fd[i][WRITE_END], write_msg, strlen(write_msg)+1);
// sleep 0, 1, 2
sleep(randomNum+1);
if (finishTime - startTime + randomNum + 1 > 30) break;
}
// Close the WRITE end of the pipe.
close(fd[i][WRITE_END]);
} else { // 5th child
// Close the unused READ end of the pipe.
close(fd[i][READ_END]);
for (;;) {
char buffer[BUFFER_SIZE] = "";
gettimeofday(&tv, NULL);
finishTime = (int) tv.tv_sec;
finishTimeMsec = (int) ((tv.tv_usec) / 1000);
// prompt INPUT for the 5th child
printf("Input Message: ");
scanf("%[^\n]%*c", buffer);
gettimeofday(&tv, NULL);
int inputTime = (int) tv.tv_sec;
sprintf(write_msg, "0:%2d.%d: Child %d (PID=%d): %s\n", finishTime- startTime, finishTimeMsec, 5, getpid(), buffer);
printf("%s", write_msg);
// Write from the WRITE end of the pipe.
write(fd[i][WRITE_END], write_msg, strlen(write_msg)+1);
if (inputTime - startTime > 30) break;
}
// Close the WRITE end of the pipe.
close(fd[i][WRITE_END]);
}
status++;
} else {
fprintf(stderr, "fork() failed");
return 1;
}
}
fclose(fp);
return 0;
}