LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Hanging while using msgsnd and msgrcv (https://www.linuxquestions.org/questions/programming-9/hanging-while-using-msgsnd-and-msgrcv-4175563911/)

sanddune 01-14-2016 06:04 AM

Hanging while using msgsnd and msgrcv
 
Hi All,

I see a hang on executing below source..
> Can we have have msgsnd and msgrcv between processes?Examples?
> I understand the parent process is hung msgrcv, What is wrong with this approach?

Below is the code:
Code:

int main()
{
        int rv;//,pfds[2];
        pid_t pid; //char buff[20];
       
        //pipe(pfds);
        pid = fork();
           
        switch(pid)
        {
                case -1:
                perror("fork");
                exit(1);
               
                case 0:
                {
                        key_t key; int msgqid;
                        mymsg_stuct msgdata; //= {2,{"Aidan",23}};
                        //strcpy(msgdata.mine_info.name,"Aidan");
                        msgdata.mine_info.empid = 23;
                        msgdata.mine_info.k = 23;
                        key = ftok("/home/dance/",9);
                        msgqid = msgget(key,0666| IPC_CREAT);
                        msgsnd(msgqid,&msgdata,sizeof(struct data),0);
                       
                        printf("Child process: \n");
                        printf("My parents id: %d\n",getppid());
                        printf("My id: %d gid:%d %d\n",getpid(),getpgid(0));
                        //write(pfds[1],"anoop",strlen("anoop")+1);
                        //printf("Sleep for 15secs: %d\n",sleep(15));
                        scanf("%d\n",&rv);
                        exit(rv);
                }
                default:
                {
                        key_t key; int msgqid;
                        mymsg_stuct msgdata;
                        key = ftok("/home/dance/",9);
                        msgqid = msgget(key,0666| IPC_CREAT);

                        printf("Parent process: \n");
                        printf("My Child id: %d\n",pid);
                        printf("My id: %d gid:%d %d\n",getpid(),getpgid(0),getpgid(pid));
                        printf("PARENT: I'm now waiting for my child to exit()...\n");
                        msgrcv(msgqid,&msgdata,sizeof(struct data),2,0);
                        //read(pfds[0],buff,6);
                        printf("Rcv from child %s\n",msgdata.mine_info.k);
                        wait(&rv);
                        printf("PARENT: My child's exit status is: %d\n", WEXITSTATUS(rv));
                }
        }
        return 0;
}


Thanks in Advance..

Keith Hedger 01-15-2016 07:21 AM

On this line:
Code:

...
msgrcv(msgqid,&msgdata,sizeof(struct data),2,0);
...

The last arg tells msgrcv to wait for a mesage, you should use 'IPC_NOWAIT' defined in /usr/include/bits/ipc.h, but you should not include that file directly as it says in the header, just use #include <sys/msg.h>

sundialsvcs 01-15-2016 09:43 AM

No, that's not it. The parent process needs to wait for a message.

Are you checking the result of all these calls to see if an error occurred?

sanddune 01-17-2016 11:40 PM

Thanks for the reply.....

I have modified the source with following:

Code:

                        msgsnd(msgqid,&msgdata,sizeof(struct data),IPC_NOWAIT);
                        printf("msgsnd error : s\n",strerror(errno));

                        msgrcv(msgqid,&msgdata,sizeof(struct data),2,IPC_NOWAIT);
                        printf("Msgrcv error : s\n",strerror(errno));




Observations are it is now able to receive ....but junk and also the child process is not exiting
hence the hang....


Following is the output:



Code:

msgsnd error : Invalid argument
Child process:
My parents id: 9735
My id: 9736 gid:9735 2048
Parent process:
My Child id: 9736
My id: 9735 gid:9735 9735
PARENT: I'm now waiting for my child to exit()...
Msgrcv error : No message of desired type
Rcv from child 134514032  ---------------- > some junk value why?


Keith Hedger 01-18-2016 02:20 AM

Have a look at the man pages for msgsnd/msgrcv, also this may help, its quite old but still works:
http://cli-apps.org/content/show.php...content=148626

Keith Hedger 01-18-2016 02:26 AM

what is 'mymsg_stuct' and 'data' defined as? we really need to know what your private data structures are defined as so the code can be debugged properly.

sanddune 01-18-2016 07:48 AM

struct pdata{
long mtype;
struct data
{
//char name[30];
int k;
int empid;
}mine_info;
};
typedef struct pdata mymsg_stuct;

Keith Hedger 01-18-2016 11:01 AM

Right took some sorting but this
Code:

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

struct pdata
{
        long mtype;
        struct data
        {
//char name[30];
                int k;
                int empid;
        } mine_info;
};
typedef struct pdata mymsg_stuct;

int main()
{
        int rv;//,pfds[2];
        pid_t pid; //char buff[20];
       
        //pipe(pfds);
        pid = fork();
           
        switch(pid)
        {
                case -1:
                perror("fork");
                exit(1);
               
                case 0:
                {
                        key_t key; int msgqid;
                        mymsg_stuct msgdata; //= {2,{"Aidan",23}};
                        msgdata.mtype=666;
                        //strcpy(msgdata.mine_info.name,"Aidan");
                        msgdata.mine_info.empid = 23;
                        msgdata.mine_info.k = 23;
                        key = ftok("/home/dance/",9);
                        msgqid = msgget(key,0666| IPC_CREAT);
                        msgsnd(msgqid,&msgdata,sizeof(struct data),0);
                       
                        printf("Child process: \n");
                        printf("My parents id: %d\n",getppid());
                        printf("My id: %d gid:%d %d\n",getpid(),getpgid(0));
                        //write(pfds[1],"anoop",strlen("anoop")+1);
                        //printf("Sleep for 15secs: %d\n",sleep(15));
                        //scanf("%d\n",&rv);
                        exit(0);
                }
                default:
                {
                        key_t key; int msgqid;
                        mymsg_stuct msgdata;
                        key = ftok("/home/dance/",9);
                        msgqid = msgget(key,0666| IPC_CREAT);

                        printf("Parent process: \n");
                        printf("My Child id: %d\n",pid);
                        printf("My id: %d gid:%d %d\n",getpid(),getpgid(0),getpgid(pid));
                        printf("PARENT: I'm now waiting for my child to exit()...\n");
                        msgrcv(msgqid,&msgdata,sizeof(struct data),666,0);
                        //read(pfds[0],buff,6);
                        printf("Rcv from child %i\n",msgdata.mine_info.k);
                        wait(&rv);
                        printf("PARENT: My child's exit status is: %d\n", WEXITSTATUS(rv));
                }
        }
        return 0;
}

Works!

To start you was hanging on the scanf after sending the msg so the child was not exiting, second you have to set 'msgdata.mtype' which is a simple message type id ( in this case '666' ), you were setting it to '2' in the msgrcv but not setting it before using msgsnd.
The reason you were getting nonsense or a segfault when getting the msg is that your printf expects a null terminated c string but you are giving it an int, so use "printf("Rcv from child %i\n",msgdata.mine_info.k);"

Hope this helps.

sanddune 01-18-2016 11:43 PM

Thanks for your time!!!!!

What is the reason for the child process to hang with scanf() around?....my objective was to read a value and send it across the parent?

Keith Hedger 01-19-2016 05:37 AM

scanf read from stdin so it was just sitting waiting for input, its not the best way to get input as it can overflow the buffer, see the man page.
Don't forget to mark the thread SOLVED, and you can click on the 'Did you find this post helpful? Yes' link if you want ;)


All times are GMT -5. The time now is 06:35 PM.