首页 > 解决方案 > 为什么 msgrcv() 将 msqid 设置为 0?

问题描述

我在 c 中有一个程序,它应该通过 msgq 发送和接收 ipc 消息。

我遇到的问题是,当我运行msgrcv()它时,它会将我的全局设置int msqid为 0。当然,我在其他方法中需要它,比如在信号处理程序中。

这是一些代码:

/* all the includes and some variables*/
#include "msg.h" // include the one I made
int msgQ; // global int

int main(int argc, char *argv[])
{
    key = ftok("progfile", 65);
    msgQ = msgget(key, 0666 | IPC_CREAT);
    printf("msg queue id: %d \n", msgQ);

    start_tik_tok(); // setting up the timer and the signal handler
    /* irrelevant code */

    void read_msgs(msgQ);
}

void read_msgs(int msgQid)
{
    while (1)
    {
        printf("before the read local:%d goval:%d\n", msgQid, msgQ);
        int ret = msgrcv(msgQid, &message, sizeof(message), 1, 0);
        printf("after the read local:%d global :%d\n", msgQid, msgQ);
        if (ret == -1)
            /* error handling */

        switch (message.action_type)
        {
            /* mesage handling */
        }
}

void signal_handler(int signo)
{
    /*I need the global int here to send some messages */
}

void start_tik_tok()
{
    //timer interval for setitimer function
    struct itimerval timer;
    timer.it_interval.tv_sec = 1; //every 1 seconds
    timer.it_interval.tv_usec = 0;
    timer.it_value.tv_sec = 1; //start in 1 seconds
    timer.it_value.tv_usec = 0;

    //action for the signal
    struct sigaction new_sa;
    memset(&new_sa, 0, sizeof(new_sa));
    new_sa.sa_handler = &signal_handler;

    sigaction(SIGALRM, &new_sa, NULL);
    setitimer(ITIMER_REAL, &timer, NULL);
}

msg.h文件:

#include <sys/msg.h>

struct msg_buff{
    long mesg_type; //reciver
    int sender; //sender
    char action_type;
    char time_tiks; //time in tiks
} message;

输出:

消息队列 ID:45416448

在读取 local:45416448 global:45416448 之前

读完local:45416448 global:0之后

...

您可以看到,在我运行之后msgrcv(),值msgQ变为 0,即使我使用变量将值传递给方法read_msgs()

标签: cmessage-queue

解决方案


The msgrcv function takes a pointer to a structure that starts with a "header" of type long, followed by the message data. The third argument to msgrcv, msgsz, is the size of the message data body, not including the long that's the header. So you should pass something like sizeof message - sizeof(long). By passing sizeof message, you're asking it to overflow the buffer sizeof(long) bytes, and this is clobbering some other global variable.


推荐阅读