Очереди сообщений System V в Linux не работают должным образом

У меня есть следующее приложение, которое воспроизводит проблему, с которой я сталкиваюсь в более крупном приложении с очередями сообщений system v. в основном функция main генерирует ключ, а затем создает очередь сообщений с помощью msgget (). Затем появляются 3 вилки, каждая с разными идентификаторами. каждый из них запускает msgrcv с другим положительным номером (поэтому они ждут разных сообщений).

Затем Main засыпает на несколько секунд и отправляет сообщение на 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, установленный на точно 2. 3 для 3 и так далее. Моей точкой отсчета было это руководство: http://www.ecst.csuchico.edu/~beej/guide/ipc/mq.html. Кто-нибудь может помочь, пожалуйста? (вам может потребоваться изменить строку кода ftok, чтобы она указывала на действительный файл на вашем собственном компьютере для успешного тестирования). Я использую Fedora 10 на EeePC 1000H

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
1 242
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ах, думаю, я исправил это. Это потому, что я использовал int, а не long для первого набора членов в структуре для «mtype». передача вместо этого {1l, "hello"} и изменение определения i на long, похоже, исправили его

Согласно POSIX, возвращаемое значение из msgget () является целым числом, а не длинным. Согласно POSIX первым аргументом msgsnd () является int, а не длинный. Если вы работаете с 32-разрядной версией, возможно, все будет в порядке; если у вас есть свои прототипы в области видимости (как вам кажется), компилятор C тоже сделает это за вас.

Jonathan Leffler 24.12.2008 07:39

Вы знаете о opengroup.org/onlinepubs/009695399/toc.htm, не так ли? Это спецификация POSIX. Вам также понадобится ваша местная спецификация на случай, если платформа не совместима с POSIX.

Jonathan Leffler 24.12.2008 07:40

Кроме того, ваш код разделяет только 3 детей; использование 4 в качестве константы сбивает с толку. Кроме того, фраза «созданы 3 вилки» - это очень странный жаргон. «3 ребенка разветвлены» будет на языке Linux; «3 ребенка созданы» было бы нормально, хотя и не очень точным, поскольку есть posix_spawn (), который имеет дело с spawn.

Jonathan Leffler 24.12.2008 07:44

извините, я отредактировал это, потому что я использовал слово "идентификатор очереди сообщений", когда я должен был сначала сказать структуры mtype

Philluminati 28.12.2008 23:14

Другие вопросы по теме