使用消息操作的二进制信号量

时间:2014-05-12 16:32:26

标签: c linux multithreading semaphore

我需要在Linux中使用消息操作(msgrcv,msgsnd,msgctl)实现二进制信号量。 我的代码:

#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;
}

据我了解消息操作的机制,第一条消息是使用FLAG 0发送的,而不是IPC_NOWAIT,因此第二条消息将无法发送。事实上,我的程序正确打印旧消息,但尝试发送第二条消息并不会按预期结束错误。

修改

演习的主要目标是: “使用频道和消息创建二进制信号量。”指令中的示例仅包括这四个函数用法(msgget,msgsnd,msgctl,msgrcv)和一些标志。

1 个答案:

答案 0 :(得分:1)

man 7 svipc看来,SysV消息队列的唯一限制是队列中存在的总字节数。因此,您有两个解决方案:

  • 使用msgctl将最大字节数设置为一条消息的大小,并仅使用此精确大小的消息
  • 使用POSIX消息队列,允许您指定mq_open的最大消息数