0
votes

I created the two producers and two consumers, producer1 sent to consumer1 two integer number and consumer1 print the sum of numbers, and I have another consumer and producer, producer2 sent to consumer2 the path for folder and consumer2 print the all files from directory (ls command from linux). An now I want to merge together this, for example I want as all producers and consumer to use the same message queue.

This is my code for producer1: //IPC_msgq_send.c

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXSIZE     128

struct msgbuf
{
    long    mtype;
    char    mtext[MAXSIZE];
};

int main() {
    int msqid;
    // int msgflg = IPC_CREAT | 0666;
    key_t key;
    struct msgbuf sbuf;
    size_t buflen;

    key = ftok(".", 'g');

    //Get the message queue ID for the given key
    if ((msqid = msgget(key, IPC_CREAT | 0666 )) < 0) {
      perror("Could not get message queue\n");
      exit(1);
    }
    printf("MSQID value: %d\n", msqid);
    //Message Type
    sbuf.mtype = 1;
    printf("Enter a path for a folder : ");
    scanf("%[^\n]",sbuf.mtext);

    // getchar();

    buflen = strlen(sbuf.mtext) + 1 ;

    if (msgsnd(msqid, &sbuf, buflen, IPC_NOWAIT) < 0)
    {
        printf ("%d, %ld, %s, %d\n", msqid, sbuf.mtype, sbuf.mtext, (int)buflen);
        perror("Could not send message!\n");
        exit(1);
    }
    else
        printf("Message Sent\n");

    exit(0);
}

Consumer1:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXSIZE 128

struct msgbuf
{
    long    mtype;
    char    mtext[MAXSIZE];
};
int main() {
  int msqid;
  key_t key;
  struct msgbuf rcvbuffer;
  char pathForPrint[1024] = "";

  // key = 1234;
  key = ftok(".", 'g');

  if ((msqid = msgget(key, 0666)) < 0) {
    perror("Could not get message queue\n");
    exit(1);
  }
  printf("MSQID value: %d\n", msqid);
  //  Receive an answer of message type 1.
  if (msgrcv(msqid, &rcvbuffer, MAXSIZE, 1, 0) < 0) {
    perror("Could not receive message!\n");
    exit(1);
  }

   //printf("%s\n", rcvbuffer.mtext);
  strcat(pathForPrint, "ls ");
  strcat(pathForPrint, rcvbuffer.mtext);
  system(pathForPrint);
 return 0;
}

Producer2:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define VECTOR_SIZE 2

struct msgbuf
{
    long    mtype;
    int     vector[VECTOR_SIZE];
};

int main() {
    int msqid;
    // int msgflg = IPC_CREAT | 0666;
    key_t key;
    struct msgbuf sbuf;
    size_t buflen;
    int i;

    key = ftok(".", 'g');

    //Get the message queue ID for the given key
    if ((msqid = msgget(key, IPC_CREAT | 0666 )) < 0) {
      perror("Could not get message queue\n");
      exit(1);
    }
    printf("MSQID value: %d\n", msqid);
    //Message Type
    sbuf.mtype = 1;
    while(1){
        printf("Enter a message to add to message queue : ");
        for(i = 0; i < 2; i++){
            scanf("%d",&(sbuf.vector[i]));

            buflen = sizeof(sbuf.vector[i]) + 1 ;
        }

    // getchar();

        if (msgsnd(msqid, &sbuf, buflen, IPC_NOWAIT) < 0)
        {
            printf ("%d, %ld, %d, %d, %d\n", msqid, sbuf.mtype, sbuf.vector[0], sbuf.vector[1], (int)buflen);
            perror("Could not send message!\n");
            exit(1);
        }
        else
            printf("Message Sent\n");

        sleep(3);
    }

    exit(0);
}

Consumer2:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 128

#define VECTOR_SIZE 2

struct msgbuf
{
    long    mtype;
    int     vector[VECTOR_SIZE];
};
int main() {
    int msqid;
    key_t key;
    struct msgbuf rcvbuffer;

    // key = 1234;
    key = ftok(".", 'g');
    while(1){  
      if ((msqid = msgget(key, 0666)) < 0) {
        perror("Could not get message queue\n");
        exit(1);
      }
      printf("MSQID value: %d\n", msqid);
      //  Receive an answer of message type 1.
      if (msgrcv(msqid, &rcvbuffer, MAXSIZE, 1, 0) < 0) {
        perror("Could not receive message!\n");
        exit(1);
      }

      printf("%d\n", (rcvbuffer.vector[0] + rcvbuffer.vector[1]));
    }
    return 0;
}

For use the same queue is necessary to have the same key, but how to make it ?

Thank you!

1
That does not look appropriate to me. A common queue makes sense if any of the consumers can handle any of the messages, which is not the case in your example. What would consumer 2 do if next message in the queue it gets actually is for consumer 1 and vice versa?Aconcagua
@Aconcagua: that is what the message type is for.Matthias

1 Answers

1
votes

The key is a randomly selectable integer. If you generate the key with ftok(), you get the same key as long you refer to the same path and the same id, cf. the man page. If you want the same key, it is a bad idea to use a relative path (as you did), since your programs may have different directories. Use an absolute path.

However, please consider the remark of Aconcagua. If you use a common queue, you need different type ids (you use id=1 for both).