General
cancel
Showing results for 
Search instead for 
Did you mean: 

A strange problem of message queue

山本二十八
Occasional Visitor

A strange problem of message queue

Hi all!

    There are 2 processes reading from a common message queue in different type(BLOCK MODE). Process 1 with type 11, and process 2 with type 12. Then send 2 packages to the message queue of type 11.

 

#include <iostream>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <pthread.h>
#include <unistd.h>
#include <assert.h>

using namespace std;

int __id; 
int __type = -1;

int rcv_proc()
{
        for(;;)
  {
          char      buf[2048 + sizeof(long)];
          memset(buf, 0, sizeof(buf));
                fprintf(stdout, "++msgrcv(__id=%d,type=%d)\n", __id, __type);
                
          struct msgbuf *mb;
          mb = (struct msgbuf *)buf;
        
          int nread = msgrcv(__id, mb, 2048, __type, 0);
          if (nread == -1)
                {
                    fprintf(stderr, "msgrcv fail, errno=%d,errmsg=%s\n", errno, strerror(errno));
                    exit(1);
                }
                fprintf(stdout, "getmsg:%s\n", (char*)mb->mtext);
                fprintf(stdout, "--msgrcv(id=%d,type=%d)\n",__id, __type);
  }
        return 0;
}

int snd_proc()
{
        #define MSG "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"

        struct msgbuf *mb;
  char buf[2048 + sizeof(long)];
  memset(buf, 0, sizeof(buf));

  mb = (struct msgbuf *) buf;
  mb->mtype = __type;
  memcpy(mb->mtext, MSG, strlen(MSG));
        if(msgsnd(__id, mb, strlen(MSG), 0) != 0)
        {
                cerr << "msgsnd fail" << endl;
                exit(2);
        }
        
        return 0;
}
int main(int argc, char* argv[])
{
  int ch;
  bool create = false;
  int mode = -1;
  while((ch = getopt(argc, argv, "rst:c")) != -1)
  switch(ch)
  {
          case 'r':
                  mode = 0;
                  break;
          case 's':
                  mode = 1;
                  break;
          case 't':
                  __type = atoi(optarg);
                  break;
          case 'c':
                  create = true;
                  break;
          default:
                  exit(0);
  };


        int key ;
        
        if(mode != 0 && mode != 1)
        {
                cerr << "error args" << endl;
                exit(1);
        }
        if(__type <= 0)
        {
                cerr << "need type" << endl;
                exit(1);
        }
        
        char* msgpath="/home/jfmgt/1_3_source/src/soos/zxapp/test_hbt";
        key=ftok(msgpath,'a');
        cout << "key = " << key << endl;
        
        //创建消息队列
        
        int gflags=0; //IPC_CREAT|IPC_ALLOC;
        if(create)
        {
                gflags = 0660|IPC_CREAT|IPC_EXCL;
        }
        else
                gflags = 0600;
        
  __id = msgget(key,gflags);
        
        if ( __id == -1)
        {
          cerr << "msgget fail" << endl;
          exit(2);
  }
        cout << "__id = " << __id << endl;
  
        if(mode == 0)
                rcv_proc();
        else
                snd_proc();

  return 0;
}

test method

1)a.out -c -r -t11

jftest5*cash-/home/jfmgt/1_3_source/src/soos/zxapp/test_hbt >a.out -c -r -t11
key = 1629573450
__id = 20971536
++msgrcv(__id=20971536,type=11)
2) a.out -r -t12
3) a.out -s -t11 ==> 1st process receive a message

getmsg:0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
--msgrcv(id=20971536,type=11)
++msgrcv(__id=20971536,type=11)

4)a.out -s -t11 ==》1st process do not receive a message now,with ipcs -qa,you can see a message in the message queue
ipcs -qa|grep `whoami`
q   24117268 0x6121514a -Rrw-rw----     jfmgt   ztesoft     jfmgt   ztesoft    100     1  16384 15311 11847  0:50:58  0:50:53  0:50:30

5)if kill the second process, 1st process will receive the second message.


and if send a more message of type 11 to the msgq again(with a.out -s t11), the 1st process will receive 2 messages at the same time.

 

Can someone help me? Thanks!