Posix队列。接收和优先事项

时间:2014-04-18 17:08:44

标签: posix priority-queue fork

我想要的是:

- > 1个创建4个进程的主进程,从子进程接收消息并处理它们,打印收到的内容。应在NORMAL消息之前处理URGENT消息。 当一个CRITICAL优先级消息到达时,父节点应该中断处理另一个消息,并且在这些消息完成后立即处理这些消息,父进程可以继续处理NORMAL和URGENT优先级消息。

- >孩子们只是以随机优先级向父母发送消息

此外,CTRL + C被捕获,因此当它发生时,孩子死亡,父母等待直到孩子完成,然后,父母完成。

我的问题是两个:

  1. 如何按照我上面解释的方式处理优先事项。
  2. 这可能是愚蠢的,但我仍然不知道为什么,但在父代码中,当它收到一条消息时说:消息太长,我无法解决它不要知道发生了什么。
  3. 这是我的代码:

    #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);
    }
    

1 个答案:

答案 0 :(得分:2)

这是可能的,因为你永远不会unlink你的队列,你在不知不觉中使用以前创建的队列。如果创建的旧队列的消息大小大于 msg_len 参数,则传递给mq_receive,这将解释您的“消息太长”(EMSGSIZE)错误。

在运行程序之前尝试删除任何现有队列。如果它们尚未安装,您可以安装这样的队列:

sudo mkdir /dev/mqueue
sudo mount -t mqueue none /dev/mqueue

然后,您可以执行常规文件操作,例如ls /dev/mqueuerm /dev/mqueue/queue.txt

(注意:“queue.txt”是一个非常糟糕的名字。它不是一个文本文件。)