LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-06-2009, 05:41 AM   #1
sd9
Member
 
Registered: Apr 2009
Posts: 53

Rep: Reputation: 15
Message queue items not being removed


I've tried adding items to a message queue, and it works.
When I tried to remove it, it does not remove it.
The code I've used is given below. Isn't msgrcv() supposed to remove the items from the queue?
Code:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

main()
{
        key_t key;
        int msqid=0;
        int pmb=934,inp=0,reply=1;

        printf("Add to queue? [1=y/0=n]\n");
        scanf("%d",&reply);

        if (reply==1)
        {
                key = ftok("/home/beej/somefile", 'b');
                msqid = msgget(key, 0666 | IPC_CREAT);
                msgsnd(msqid, &pmb, sizeof(pmb), 0);  /* put it onto the queue */

                //printf("\nJust a sec...\n");
                //scanf("%d",&inp);
        }
        printf("Removing it from queue\n");

        /*-----------get it off the queue-----------*/

        key = ftok("/home/beej/somefile", 'b');
        msqid = msgget(key, 0666 | IPC_CREAT);

        msgrcv(msqid, &pmb, sizeof(pmb), 2, 0);  /* get it off the queue */


}/*main*/
 
Old 07-08-2009, 08:14 AM   #2
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
Moved: This thread is more suitable in <Programming> and has been moved accordingly to help your thread/question get the exposure it deserves.
 
Old 07-08-2009, 10:04 AM   #3
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
When you write a message, part of that message is the message type. Ordinarily, one uses as the message, a struct, with the first element being the long int mtype field, followed by the message payload. This field must agree with the mtype parameter (4th param) in the call to msgrcv().
You seem to be using Beej's Guide (good), so go back and read more carefully.

--- rod.
 
Old 07-08-2009, 10:10 AM   #4
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
I agree. Another good source of information is the man-pages.

I threw this little program together using the information I gathered (from the man-page):
Code:
#include <sys/msg.h>
#include <stdio.h>
#include <assert.h>


/* user defined data structure */
struct Data
{
   int value;
};

const unsigned int DATA_TYPE = 5;

/* user defined Message Queue data transport buffer */
struct MsgBuf
{
   long        mtype;
   struct Data data;
};


int main()
{
   key_t  key   = ftok("somefile", 'b');
   int    msqid = msgget(key, 0666 | IPC_CREAT);
   struct MsgBuf msg;
   struct MsgBuf rcvmsg;

   /* prepare message transport buffer that will be sent */
   msg.mtype      = DATA_TYPE;
   msg.data.value = 123;

   /* send the transport buffer */
   printf("Writing to the queue...\n");
   assert(msgsnd(msqid, &msg, sizeof(msg), 0) == 0);

   /* receive the transport buffer */
   printf("Removing from queue...\n");
   assert(msgrcv(msqid, &rcvmsg, sizeof(rcvmsg), DATA_TYPE, 0) == sizeof(struct MsgBuf));

   printf("value = %d\n", rcvmsg.data.value);

   return 0;
}
I don't know if I did it correctly, that is, with respect to the MsgBuf struct I created, but the program does send and receive the data.
 
Old 07-09-2009, 05:49 AM   #5
sd9
Member
 
Registered: Apr 2009
Posts: 53

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by dwhitney67 View Post
I agree. Another good source of information is the man-pages.

I threw this little program together using the information I gathered (from the man-page):
Code:
#include <sys/msg.h>
#include <stdio.h>
#include <assert.h>


/* user defined data structure */
struct Data
{
   int value;
};

const unsigned int DATA_TYPE = 5;

/* user defined Message Queue data transport buffer */
struct MsgBuf
{
   long        mtype;
   struct Data data;
};


int main()
{
   key_t  key   = ftok("somefile", 'b');
   int    msqid = msgget(key, 0666 | IPC_CREAT);
   struct MsgBuf msg;
   struct MsgBuf rcvmsg;

   /* prepare message transport buffer that will be sent */
   msg.mtype      = DATA_TYPE;
   msg.data.value = 123;

   /* send the transport buffer */
   printf("Writing to the queue...\n");
   assert(msgsnd(msqid, &msg, sizeof(msg), 0) == 0);

   /* receive the transport buffer */
   printf("Removing from queue...\n");
   assert(msgrcv(msqid, &rcvmsg, sizeof(rcvmsg), DATA_TYPE, 0) == sizeof(struct MsgBuf));

   printf("value = %d\n", rcvmsg.data.value);

   return 0;
}
I don't know if I did it correctly, that is, with respect to the MsgBuf struct I created, but the program does send and receive the data.
Yay! I've done it at last. Thanks dwhitney67
I referred your code and was able to make corrections in mine. Took a long time though...
Corrected code:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

main()
{
        key_t key;
        int msqid=0;
        int pmb=934,inp=0,reply=1;

        printf("Add to queue? [1=y]\n");
        scanf("%d",&reply);

        if (reply==1)
        {
                key = ftok("/home/beej/somefile", 'b');
                msqid = msgget(key, 0666 | IPC_CREAT);
                msgsnd(msqid, &pmb, sizeof(pmb), 0);  /* put it onto the queue */

                //printf("\nJust a sec...\n");
                //scanf("%d",&inp);

                printf("Remove from queue? [1=y]");
                scanf("%d",&reply);
                if (reply==1)
                {
                        printf("Removing it from queue\n");

                        /*-----------get it off the queue-----------*/
                        //key = ftok("/home/beej/somefile", 'b');
                        //msqid = msgget(key, 0666 | IPC_CREAT);
                        msgrcv(msqid, &pmb, sizeof(pmb), 0, 0);  /* get it off the queue */
                }//if
        }//if


}/*main*/
 
Old 07-09-2009, 09:24 AM   #6
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Just a couple of comments...
In many/most cases, the queue will be used by multiple processes, as distinct from your example code, where the producer and consumer are in a single process, and share the same queue ID variable. So, all processes will have to open a message queue, and acquire their own message queue IDs. Each process can open the queue with different permissions, as appropriate.
Along the same lines, again in most cases, the consumer will expect that the queue already exists, and not use the O_CREAT flag to open the queue. If this flag is not used, the msgget() call will fail, and return -1, which the caller can use to detect that there is probably no producer process, and act accordingly. The key returned by ftok() will probably be -1, if the path argument is a pathname of a non-existant file (as I suspect is the case in your example code). You should check the return values from these two functions, and take the appropriate branch as necessary.
There exists the handy tool ipcs, for examining and managing the state of queues and other IPC methods on a host.
--- rod.
 
Old 07-09-2009, 09:37 AM   #7
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Thanks for the info theNbomr. I just remembered that one thing I forgot to do in my sample program was to remove the message queue once I was done with it. This was quite apparent when I ran "ipcs".

@ the OP:

Make sure you insert this call when you are done using your message queue:
Code:
...

msgctl(msqid, IPC_RMID, 0);
 
Old 07-09-2009, 11:20 PM   #8
sd9
Member
 
Registered: Apr 2009
Posts: 53

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by theNbomr View Post
Just a couple of comments...
Thanks for posting....there's also the ipcrm tool which comes in handy.


@dwhitney67: Thanks for the msgctl(). Needed that one too. Works like a charm!

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

main()
{
        key_t key;
        int msqid=0;
        int pmb=934,inp=0,reply=1;

        printf("Add to queue? [1=y]\n");
        scanf("%d",&reply);

        if (reply==1)
        {
                key = ftok("/home/beej/somefile", 'b');
                msqid = msgget(key, 0666 | IPC_CREAT);
                msgsnd(msqid, &pmb, sizeof(pmb), 0);  /* put it onto the queue */

                //printf("\nJust a sec...\n");
                //scanf("%d",&inp);

                printf("Remove from queue? [1=y]");
                scanf("%d",&reply);
                if (reply==1)
                {
                        printf("Removing it from queue\n");

                        /*-----------get it off the queue-----------*/
                        //key = ftok("/home/beej/somefile", 'b');
                        //msqid = msgget(key, 0666 | IPC_CREAT);
                        msgrcv(msqid, &pmb, sizeof(pmb), 0, 0);  /* get it off the queue */
                }//if

                printf("Delete the queue? [1=y]");
                scanf("%d",&reply);
                if (reply==1)
                {
                        msgctl(msqid, IPC_RMID, 0);
                        printf("Removed from queue");
                }
        }//if
}//main

Last edited by sd9; 07-10-2009 at 12:07 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Is it possible for me to write in front of queue in case of message queue? hemanthv414 Linux - Newbie 1 11-17-2008 04:40 PM
Message Queue sarcastodon Programming 0 12-26-2006 10:09 AM
send PID through message queue mariogarcia Programming 14 08-18-2006 09:51 AM
programming for message queue and such ... feetyouwell Programming 0 10-18-2004 04:54 PM
Qmail Message Queue dadepfan Linux - Software 0 07-22-2004 03:54 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:28 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration