// process communication using message queue
// ack version
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MSGLEN (16)
enum {
MSGTYPE_TEXT = 1,
MSGTYPE_ACK,
};
struct msgbuf {
long type;
char text[MSGLEN];
};
void die(const char* msg) {
perror(msg);
exit(1);
}
int main() {
int i;
// get key
key_t msgkey = ftok("temp", 'A');
if (msgkey == -1) die("ftok()");
int msgqid = msgget(msgkey, IPC_CREAT);
if (msgqid == -1) die("msgget()");
pid_t pid = fork();
if (pid < 0) {
die("fork()");
} else if (pid == 0) {
// child process
struct msgbuf msgs[6];
struct msgbuf ack;
const char* texts[] = {"first", "second", "third", "forth", "fifth", "q"};
while (1) {
msgs[i].type = MSGTYPE_TEXT;
strcpy(msgs[i].text, texts[i]);
if (msgsnd(msgqid, &msgs[i], MSGLEN, 0) == -1) die("msgsnd()");
if (msgrcv(msgqid, &ack, MSGLEN, MSGTYPE_ACK, 0) == -1) die("ackrcv()");
printf("snd %s\n", msgs[i].text);
if (msgs[i].text[0] == 'q') break;
i++;
}
return 1;
} else {
// parent process
struct msgbuf msg;
struct msgbuf ack = {MSGTYPE_ACK, ""};
while (1) {
if (msgrcv(msgqid, &msg, MSGLEN, MSGTYPE_TEXT, 0) == -1) die("msgrcv()");
if (msgsnd(msgqid, &ack, MSGLEN, 0) == -1) die("acksnd()");
printf("rcv %s\n", msg.text);
if (msg.text[0] == 'q') break;
}
return 2;
}
}