У меня есть следующее приложение, которое воспроизводит проблему, с которой я сталкиваюсь в более крупном приложении с очередями сообщений 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





Ах, думаю, я исправил это. Это потому, что я использовал int, а не long для первого набора членов в структуре для «mtype». передача вместо этого {1l, "hello"} и изменение определения i на long, похоже, исправили его
Вы знаете о opengroup.org/onlinepubs/009695399/toc.htm, не так ли? Это спецификация POSIX. Вам также понадобится ваша местная спецификация на случай, если платформа не совместима с POSIX.
Кроме того, ваш код разделяет только 3 детей; использование 4 в качестве константы сбивает с толку. Кроме того, фраза «созданы 3 вилки» - это очень странный жаргон. «3 ребенка разветвлены» будет на языке Linux; «3 ребенка созданы» было бы нормально, хотя и не очень точным, поскольку есть posix_spawn (), который имеет дело с spawn.
извините, я отредактировал это, потому что я использовал слово "идентификатор очереди сообщений", когда я должен был сначала сказать структуры mtype
Согласно POSIX, возвращаемое значение из msgget () является целым числом, а не длинным. Согласно POSIX первым аргументом msgsnd () является int, а не длинный. Если вы работаете с 32-разрядной версией, возможно, все будет в порядке; если у вас есть свои прототипы в области видимости (как вам кажется), компилятор C тоже сделает это за вас.