3

I am trying to communicate with forked child process using message queue from boost interprocess library. When child process calls receive it causes exception with message

boost::interprocess_exception::library_error

I am using GCC 6.3 on Debian 9 x64.

#include <iostream>
#include <unistd.h>
#include <boost/interprocess/ipc/message_queue.hpp>
#include <memory>

int main(int argc, char* argv[])
{
    using namespace boost::interprocess;

    const char* name = "foo-552b8ae9-6037-4b77-aa0d-d4dc9dad790b";
    const int max_num_msg = 100;
    const int max_msg_size = 32;
    bool is_child = false;

    message_queue::remove(name);
    auto mq = std::make_unique<message_queue>(create_only, name, max_num_msg, max_msg_size);

    auto child_pid = fork();
    if (child_pid == -1)
    {
        std::cout << "fork failed" << std::endl;
        return -1;
    }
    else if (child_pid == 0)
    {
        is_child = true;
    }

    if (is_child)
    {
        // does child needs to reopen it?
        mq.reset( new message_queue(open_only, name) );
    }

    int send_num = 0;
    while(true)
    {
        unsigned int priority = 0;
        if (is_child)
        {
            message_queue::size_type bytes = 0;
            try
            {
                int num;
                // Always throws. What is wrong ???????
                mq->receive(&num, sizeof(num), bytes, priority);
                std::cout <<  num << std::endl;
            }
            catch(const std::exception& e)
            {
                std::cout << "Receive caused execption " << e.what() << std::endl;
            }
            sleep(1);
        }
        else
        {
            mq->send(&send_num, sizeof(send_num), priority);
            send_num++;
            sleep(5);
        }
    }


    return 0;
}

Also, in child process is it required to reopen the message queue created by the parent process? I tried it both ways and neither worked. I am getting the same exception on receive.

1 Answer 1

1

The problem is that your receive buffer is smaller than max_msg_size. Assuming 4-byte integers, this should work:

int num[8];
mq.receive(num, sizeof(num), bytes, priority);
std::cout << *num << std::endl;

Also, I see no reason to play fast and loose with the actual queue instance. Just create it per process:

#include <boost/interprocess/ipc/message_queue.hpp>
#include <boost/exception/diagnostic_information.hpp>
#include <iostream>
#include <memory>
#include <unistd.h>

int main() {
    namespace bip = boost::interprocess;

    const char *name = "foo-552b8ae9-6037-4b77-aa0d-d4dc9dad790b";
    {
        const int max_num_msg = 100;
        const int max_msg_size = 32;
        bip::message_queue::remove(name);
        bip::message_queue mq(bip::create_only, name, max_num_msg, max_msg_size);
    }

    auto child_pid = fork();
    if (child_pid == -1) {
        std::cout << "fork failed" << std::endl;
        return -1;
    }
    bip::message_queue mq(bip::open_only, name);

    if (bool const is_child = (child_pid == 0)) {
        while (true) {
            unsigned int priority = 0;
            bip::message_queue::size_type bytes = 0;

            try {
                int num[8];
                mq.receive(num, sizeof(num), bytes, priority);
                std::cout << *num << std::endl;
            } catch (const bip::interprocess_exception &e) {
                std::cout << "Receive caused execption " << boost::diagnostic_information(e, true) << std::endl;
            }
            sleep(1);
        }
    } else {
        // parent
        int send_num = 0;
        while (true) {
            unsigned int priority = 0;

            mq.send(&send_num, sizeof(send_num), priority);
            send_num++;
            sleep(5);
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.