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.

edit

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.

有帮助吗?

解决方案

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:

  • use msgctl to set the maximum number of bytes to the size of one message and use only messages of this precise size
  • use POSIX message queues instead which allow you to specify a maximum number of messages with mq_open
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top