Reputation: 91
I need to implement a binary semaphore using message operations ( msgrcv, msgsnd, msgctl ) in Linux. My code:
#include<string.h>
#include<time.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/wait.h>
#include<sys/errno.h>
extern int errno; // error NO.
#define MSGPERM 0600 // msg queue permission
#define MSGTXTLEN 60 // msg text length
int msgqid, rc;
int done;
struct msg_buf
{
long mtype;
char mtext[MSGTXTLEN];
} msg,msg2;
int main(int argc,char **argv)
{
msgqid = msgget(IPC_PRIVATE, MSGPERM|IPC_CREAT);
if (msgqid < 0)
{
perror(strerror(errno));
printf("Failed to create message with id = %d\n", msgqid);
return 1;
}
printf("Message %d created\n",msgqid);
// message to send
msg.mtype = 1; // set the type of message
sprintf (msg.mtext, "%s\n", "Old message...");
rc = msgsnd(msgqid, &msg, sizeof(msg.mtext), 0);
if (rc < 0)
{
perror( strerror(errno) );
printf("Could not send, rc = %d\n", rc);
}
// message to send
msg.mtype = 1; // set the type of message
sprintf (msg.mtext, "%s\n", "New message...");
rc = msgsnd(msgqid, &msg, sizeof(msg.mtext), 0);
if (rc < 0)
{
perror( strerror(errno) );
printf("Could not send, rc = %d\n", rc);
}
// read the message from queue
rc = msgrcv(msgqid, &msg, sizeof(msg.mtext), 0, 0);
if (rc < 0)
{
perror( strerror(errno) );
printf("Could not read, rc=%d\n", rc);
}
printf("Received message: %s\n", msg.mtext);
// remove the queue
rc=msgctl(msgqid,IPC_RMID,NULL);
if (rc < 0)
{
perror( strerror(errno) );
printf("Deleting message failed, rc=%d\n", rc);
}
printf("Message %d deleted\n",msgqid);
return 0;
}
As i understand the mechanics of message operations, the first message is sent with FLAG 0, not IPC_NOWAIT, so the second message won't be able to be sent. In fact my program prints the old message correctly, but attempting to send the second message does not end with an error as expected.
The main goal of the exercise is to: "Create a binary semaphore using channels and messages." The example present in the instruction includes only these four functions usage ( msgget, msgsnd, msgctl, msgrcv) and some flags.
Upvotes: 1
Views: 713
Reputation: 2762
It appears from man 7 svipc
that the only limit a SysV message queue has is the total number of bytes present in the queue. Therefore you have two solutions:
msgctl
to set the maximum number of bytes to the size of one message and use only messages of this precise sizemq_open
Upvotes: 1