When I have two different IPC message queues on Linux, sometimes the messages from the wrong queue are grabbed.
The following toy program displays the problem, can be repeated on different processors.
Any help greatly appreciated!
Bert
/*
To compile;
gcc MM.c -o mm -fno-stack-protector -pthread
We want Mickey to send a message to Minnie exclusively.
We want Donald to send a message to pluto exclusively.
Problem: Pluto intercepts Minnie's messages.
Listing gives:
$ ./mm
Mickey thread successfully started.
Minnie thread successfully started.
Pluto thread successfully started.
Donald thread successfully started.
Donald sent a message to Pluto.
Mickey sent a message to Minnie.
Pluto received: Sit, Pluto!
Minnie received: Hello, Minnie!
Mickey sent a message to Minnie. (100 times)
Pluto received: Hello, Minnie!
*/
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <string.h>
#include <stdio.h>
pthread_t t1,t2,t3,t4;
// Mickey send
key_t ipcMickey;
int mqMickeyid;
char helloMickeymsg[] = {"Hello, Minnie!"};
struct { long type; char text[100]; } myMickeymsg;
// Minnie get
int mqMinnieid;
struct { long type; char text[100]; } myMinniemsg;
// Donald send
key_t ipcDonald;
int mqDonaldid;
char helloDonaldmsg[] = {"Sit, Pluto!"};
struct { long type; char text[100]; } myDonaldmsg;
// Pluto get
int mqPlutoid;
struct { long type; char text[100]; } myPlutomsg;
static void * DONALDthreadFunc(void *arg)
{
printf("Donald thread successfully started.\n");
char *s = (char *) arg;
while(1)
{
//send
memset(myDonaldmsg.text, 0, 100);
strncpy(myDonaldmsg.text, helloDonaldmsg, strlen(helloDonaldmsg));
myDonaldmsg.type = 1;
msgsnd(mqDonaldid, &myDonaldmsg, sizeof(myDonaldmsg), 0);
printf("Donald sent a message to Pluto.\r\n");
sleep(4);
}
/* just a formality */
return (void *) strlen(s);
}
static void * PLUTOthreadFunc(void *arg)
{
printf("Pluto thread successfully started.\n");
char *s = (char *) arg;
while(1)
{
//receive
mqPlutoid = msgget(ipcDonald, 0);
msgrcv(mqPlutoid, &myPlutomsg, sizeof(myPlutomsg), 0, 0);
printf("Pluto received: %s\r\n\r\n", myPlutomsg.text);
sleep(1);
}
/* just a formality */
return (void *) strlen(s);
}
static void * MICKEYthreadFunc(void *arg)
{
printf("Mickey thread successfully started.\n");
char *s = (char *) arg;
while(1)
{
//send
memset(myMickeymsg.text, 0, 100);
strncpy(myMickeymsg.text, helloMickeymsg, strlen(helloMickeymsg));
myMickeymsg.type = 1;
msgsnd(mqMickeyid, &myMickeymsg, sizeof(myMickeymsg), 0);
printf("Mickey sent a message to Minnie.\r\n");
usleep(10000);
}
/* just a formality */
return (void *) strlen(s);
}
static void * MINNIEthreadFunc(void *arg)
{
printf("Minnie thread successfully started.\n");
char *s = (char *) arg;
while(1)
{
//receive
mqMinnieid = msgget(ipcMickey, 0);
msgrcv(mqMinnieid, &myMinniemsg, sizeof(myMinniemsg), 0, 0);
printf("Minnie received: %s\r\n\r\n", myMinniemsg.text);
sleep(3);
}
return (void *) strlen(s);
}
int main (void)
{
ipcMickey = ftok("/tmp/mqmickey", 63);
mqMickeyid = msgget(ipcMickey, IPC_CREAT | 0666);
ipcDonald = ftok("/tmp/mqdonald", 69);
mqDonaldid = msgget(ipcDonald, IPC_CREAT | 0666);
pthread_create(&t1, NULL, MICKEYthreadFunc, "Mickey sends\n");
pthread_create(&t2, NULL, MINNIEthreadFunc, "Minnie replies\n");
pthread_create(&t3, NULL, DONALDthreadFunc, "Donald sends\n");
pthread_create(&t4, NULL, PLUTOthreadFunc, "Pluto replies\n");
while(1)
{
sleep(5);
}
}