Skip to content

Commit c44aef4

Browse files
committed
Added source file, updated README
1 parent 8a54feb commit c44aef4

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# whispers
2-
Chinese Whispers implemented in C.
2+
Chinese Whispers implemented in C to demonstrate System V IPC.

whispers.c

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#include <stdlib.h>
2+
#include <stdio.h>
3+
#include <unistd.h>
4+
#include <string.h>
5+
#include <sys/stat.h>
6+
#include <sys/types.h>
7+
#include <sys/ipc.h>
8+
#include <sys/msg.h>
9+
#include <errno.h>
10+
#include <time.h>
11+
12+
#define INVALID_ARG_COUNT -31
13+
14+
int main(int argc, char **argv){
15+
16+
if(argc!=2)return INVALID_ARG_COUNT;
17+
18+
//Seed random
19+
srand(time(NULL));
20+
21+
int len = strlen(argv[1]);
22+
23+
//Create message queue
24+
int mq = msgget(IPC_PRIVATE, 0600|IPC_CREAT|IPC_EXCL);
25+
if (mq == -1) {
26+
perror("msgget");
27+
exit(-1);
28+
}
29+
30+
//Message buffer struct
31+
struct msgbuf {
32+
long mtype;
33+
char mtext[1];
34+
};
35+
36+
char* msg = argv[1];
37+
struct msgbuf *mb = (struct msgbuf*)malloc(sizeof(struct msgbuf)+len);
38+
mb->mtype = 1;
39+
40+
strcpy(mb->mtext, msg);
41+
42+
//Send to first process to start the cycle
43+
int rc = msgsnd(mq, mb, len+1, 0);
44+
if (rc == -1) {
45+
perror("msgsnd");
46+
exit(-2);
47+
}
48+
49+
int rands[len];
50+
int r;
51+
//Generate random numbers for probability calculations.
52+
for(r = 0; r<len; r++)rands[r]=rand();
53+
//Fork
54+
int i;
55+
for(i = 0; i < len; i++) {
56+
int pid = fork();
57+
if(pid < 0) {
58+
printf("Error");
59+
exit(1);
60+
} else if (pid == 0) {
61+
int p = i+1;
62+
//printf("%d alive\n", p);
63+
struct msgbuf* rMsg = (struct msgbuf*)malloc(sizeof(struct msgbuf)+len);
64+
int rc = msgrcv(mq, rMsg, len+1, p, 0);
65+
//printf("%d recieved\n", p);
66+
if (rc == -1) {
67+
perror("msgrcv");
68+
exit(1);
69+
}
70+
if((rands[i]%2)==0)rMsg->mtext[p-1]++;
71+
rMsg->mtype=p+1;
72+
if(p==len){
73+
rMsg->mtype=1;
74+
}
75+
rc = msgsnd(mq, rMsg, len+1, 0);
76+
//printf("%d sent\n", p);
77+
if(p==1){ //First child waits for last message.
78+
rc = msgrcv(mq, rMsg, len+1, p, 0);
79+
printf("%s\n", rMsg->mtext);
80+
}
81+
return 0;
82+
} else {
83+
84+
}
85+
}
86+
87+
return 0;
88+
89+
}

0 commit comments

Comments
 (0)