Search code examples
c++multithreadingboostboost-threadboost-interprocess

Unable to receive a message using message_queue in Boost thread


I have a requirement for creating a Event based Multi-thread application for which i am trying to use boost::thread and boost/interprocess/ipc/message_queue for sending messages between threads. What i am doing currently is making the thread wait in its workerfunction to wait for a message. Actually this is just for basic start where the sender and receiver both is a same thread, on later stage i have thought to store a list of message_queue corresponding for each thread and then fetch it accordingly or something like that. But now, as per the code below i am using

//in a common class

typedef struct s_Request{
int id;
}st_Request;


//in thread(XYZ) class
st_Request dataone;
message_queue *mq;

void XYZ::threadfunc(void *ptr)
{

  XYZ*obj = (XYZ*) ptr;
  obj->RecieveMsg();

}

void XYZ::RecieveMsg()
{
  message_queue mq1(open_only,"message_queue");
  if(!(mq1.try_receive(&dataone, sizeof(st_Request), recvd_size, priority)))
  printf("msg not received");

  printf("id = %d",dataone.id);
}
void XYZ::Create()
{
  mq= new message_queue(open_or_create,"message_queue",100,sizeof(st_Request));
  boost:thread workerthread(threadfunc,this);
  workerthread.join();
}

void XYZ::Send(st_Request *data)
{

  if (!(mq->try_send(data, sizeof(st_Request), 0)))
  printf("message sending failed");

}

//I am calling it like
class ABC: public XYZ
{
 ..some functions to do stuff... };
void ABC::createMSGQ()
{
  create();
  st_Request *data;
  data->id =10;
  send(data);
}

My thread is waiting in RecieveMsg but i am not getting any msg and the prints are coming till Send function entry and than the code crash. Please Guide me for what i am doing wrong, if the approach is entirely wrong, i am open to move to new approach.

P.s. this is my first question on stack overflow i tried follow the guidelines still if i strayed away anywhere please do correct.


Solution

  • st_Request *data;
    data->id =10;
    

    data is uninitialized, you cannot dereference it. Pointers should point to something before you dereference them.

    I don't understand the point of this function:

    void XYZ::Create()
    {
      mq= new message_queue(open_or_create,"message_queue",100,sizeof(st_Request));
      boost:thread workerthread(threadfunc,this);
      workerthread.join();
    }
    

    You create a new thread, then block and wait for it to finish so you can join it. Why not just do the work here, instead of creating a new thread and waiting for it to finish?

    What is threadfunc? Do you mean ThreadFunc?

    This function is written strangely:

    void XYZ::ThreadFunc(void *ptr)
    {
      XYZ*obj = (XYZ*) ptr;
      obj->RecieveMsg();
    }
    

    Why not pass the argument as XYZ* instead of void*? Boost.Thread doesn't require everything to be passed as void*. Is that function static? It doesn't need to be:

    struct XYZ {
      void threadFunc();
      void create();
      void recv();
    };
    
    void XYZ::threadFunc()
    {
      recv();
    }
    
    void XYZ::create()
    {
      boost::thread thr(&XYZ::threadFunc, this);
      thr.join();
    }