【问题标题】:System V Msg Queues on Linux don't work as expectedLinux 上的 System V 消息队列无法按预期工作
【发布时间】:2010-09-28 06:37:15
【问题描述】:

我有以下应用程序,它复制了我在具有 system v 消息队列的大型应用程序中遇到的问题。基本上,主函数生成一个密钥,然后使用 msgget() 创建一个消息队列。然后产生了 3 个分叉,每个分叉都有不同的 id。他们每个人都使用不同的正数运行 msgrcv(因此他们正在等待不同的消息)。

Main 然后休眠几秒钟 a 向 id = 3 发送一条消息。但是它不是唤醒的第三个线程,而是另一个不同的线程。此代码是完全隔离的,因此您可以自己尝试。这段代码有什么问题?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>

struct dummy_struct {
    long mtype;
    char message[255];
};

int msg_queue_id;
void recv_thread(int id);

int main(int argc, char **argv)
{
    int i;
    key_t key;
    struct dummy_struct dummy = { 3, "hello" };

    //create a unique key
    if (key = ftok("/mnt/mydocuments/code/sys_v_fork_test/main.c", 'a') == -1)
    {
        printf("ftok didn't work\n");
        exit(1);
    }

    //create the unix sys 5 message queue
    if ((msg_queue_id = msgget(key, 0644 | IPC_CREAT)) == -1)
    {
        printf("msgget failed\n");
        exit(1);
    }
    else
        printf("my message queue id: %i\n", msg_queue_id);

    //fork off multiple recievers
    for (i = 1; i < 4; i++) // <- NOTE: 1 -> 4
    {
        if (fork() == 0)
            recv_thread(i);
    }

    printf("sleeping\n");
    sleep(5);

    //wait a little then send a message

    printf("sending message\n");
    if (msgsnd(msg_queue_id, &dummy, sizeof(struct dummy_struct), 0) == -1)
    {
        printf("msgsnd failed\n");
    }
    printf("main thread exiting");
    _exit(0);
}

void recv_thread(int id)
{
    struct dummy_struct dummy;

    printf("recv_thread with id: %i\n", id);

    if (msgrcv(msg_queue_id, &dummy, sizeof(struct dummy_struct), id, 0) == -1)
        printf("error in msgrcv\n");
    else
        printf("thread %i got %s back\n", id, dummy.message);
}

如果我等待 2,这意味着消息的结构中包含的 mtype 设置为 exactly 2. 3 表示 3 等等。我的参考点是本指南:http://www.ecst.csuchico.edu/~beej/guide/ipc/mq.html。有人可以帮忙吗? (您可能需要修改 ftok 代码行以指向您自己机器上的有效文件才能成功测试)。我在 EeePC 1000H 上运行 Fedora 10

【问题讨论】:

    标签: c linux message-queue


    【解决方案1】:

    啊,我想我已经修好了。这是因为对于“mtype”结构中的第一个成员集,我使用的是 int 而不是 long。传入 { 1l, "hello" } 并将 i 的定义更改为 long 似乎已修复它

    【讨论】:

    • 根据 POSIX,msgget() 的返回值是 int,而不是 long。根据 POSIX,msgsnd() 的第一个参数是 int,而不是 long。如果您使用的是 32 位,则可能没问题;如果你的原型在范围内(就像你看起来的那样),C 编译器也会为你清理。
    • 你知道opengroup.org/onlinepubs/009695399/toc.htm,不是吗?这是 POSIX 规范。如果平台不符合 POSIX 标准,您还需要本地规范。
    • 另外,你的代码只分叉了 3 个孩子;使用 4 作为常数是令人困惑的。此外,“产生了 3 个叉子”是非常奇怪的行话。 “3 个孩子被分叉”是 Linux 语言; '3 children are spawned' 可以,虽然不是非常精确,因为有一个处理 spawn 的 posix_spawn()。
    • 对不起,我编辑了它,因为我应该先说结构的时候使用了“消息队列 id”这个词。mtype
    猜你喜欢
    • 2013-03-29
    • 2010-12-15
    • 2020-04-18
    • 1970-01-01
    • 2011-09-18
    • 2011-05-05
    • 2019-05-15
    • 1970-01-01
    • 2017-05-21
    相关资源
    最近更新 更多