我想要的是:
- > 1个创建4个进程的主进程,从子进程接收消息并处理它们,打印收到的内容。应在NORMAL消息之前处理URGENT消息。 当一个CRITICAL优先级消息到达时,父节点应该中断处理另一个消息,并且在这些消息完成后立即处理这些消息,父进程可以继续处理NORMAL和URGENT优先级消息。
- >孩子们只是以随机优先级向父母发送消息
此外,CTRL + C被捕获,因此当它发生时,孩子死亡,父母等待直到孩子完成,然后,父母完成。
我的问题是两个:
这是我的代码:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <sys/wait.h>
#include <mqueue.h>
int main()
{
srand(time(NULL));
mqd_t mqd;
struct mq_attr atributos = {.mq_maxmsg = 10, .mq_msgsize = 50};
int i;
int pid;
int status;
int num_children = 4;
char buffer[atributos.mq_msgsize];
for (i = 0; i < num_children; i++)
{
if ((pid = fork() == 0))
{
srand(time(NULL));
int prio = rand () % 3;
char* msg = "Hi dude";
strncpy (buffer, msg, sizeof(buffer));
printf("%d\n",prio);
if ((mqd = mq_open("/queue.txt", O_CREAT | O_WRONLY, 0666, &atributos)) == -1)
{
perror("child mq_open");
exit(1);
}
if (mq_send(mqd, buffer, sizeof(buffer), prio) == -1)
{
perror("mq_send");
exit(1);
}
mq_close(mqd);
exit(0);
}
}
// parent
if ((mqd = mq_open("/queue.txt", O_CREAT | O_RDONLY, 0666, &atributos)) == -1)
{
perror("parent mq_open");
exit(1);
}
unsigned int priority;
for (int i = 0; i < num_children; i++)
{
if (mq_receive(mqd, buffer, sizeof(buffer)+1, &priority) == -1)
{
perror("mq_recieve");
exit(1);
}
char * buffer_priority=NULL;
if (priority==0) {
buffer_priority = "NORMAL";
} else if
(priority == 1) {
buffer_priority = "URGENT";
}
else if
(priority == 2) {
buffer_priority = "CRITICAL";
}
printf("Received (%s): %s\n", buffer_priority, buffer);
pid_t childpid;
if ((childpid = waitpid(-1, &status, 0)) > 0)
{
if (WIFEXITED(status))
printf("PID %d exited normally. Exit status: %d\n",
childpid, WEXITSTATUS(status));
else
if (WIFSTOPPED(status))
printf("PID %d was stopped by %d\n",
childpid, WSTOPSIG(status));
else
if (WIFSIGNALED(status))
printf("PID %d exited due to signal %d\n.",
childpid,
WTERMSIG(status));
}
}
mq_close(mqd);
}
答案 0 :(得分:2)
这是可能的,因为你永远不会unlink
你的队列,你在不知不觉中使用以前创建的队列。如果创建的旧队列的消息大小大于 msg_len 参数,则传递给mq_receive
,这将解释您的“消息太长”(EMSGSIZE)错误。
在运行程序之前尝试删除任何现有队列。如果它们尚未安装,您可以安装这样的队列:
sudo mkdir /dev/mqueue
sudo mount -t mqueue none /dev/mqueue
然后,您可以执行常规文件操作,例如ls /dev/mqueue
和rm /dev/mqueue/queue.txt
。
(注意:“queue.txt”是一个非常糟糕的名字。它不是一个文本文件。)