Question

What I want is this:

-> 1 main process that creates 4 process, receives messages from the children and processes them, printing what is received. URGENT messages should be processed before NORMAL messages. When a CRITICAL priority message arrives, the parent should interrupt processing the other and inmediatly process these messages, once they are finished, the parent process can keep processing NORMAL and URGENT priority messages.

-> Children just send messages to the parent with a random priority

Also, the CTRL+C is captured, so that when it takes place, children die, the parent waits untill the children are done, and then, the parent finishes.

My problems are two:

  1. How to handle the priorities the way I explained above.
  2. This is maybe stupid but I still don't know why, but in the parent code, when it receive a message it says : message too long, and I can't solve it don't know what is happening.

This is my code:

#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);
}
Was it helpful?

Solution

It's possible because you never unlink your queue that you are unknowingly working with a previously created one. If the old queue was created with a message size larger than the msg_len parameter you are passing to mq_receive, that would explain your "Message too long" (EMSGSIZE) errors.

Try deleting any existing queues before you run the program. If they aren't already mounted you can mount the queues like so:

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

You can then perform normal file operations like ls /dev/mqueue and rm /dev/mqueue/queue.txt.

(Note: "queue.txt" is a pretty awful name. It's not a text file.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top