[C++-sig] boost python wrapping boost message queue problem
袁振飞
zf.yuan.y at gmail.com
Wed Jan 7 15:19:57 CET 2015
Hi all.
I wrapped the boost ipc message queue into Python using Boost.Python.
Everything goes fine except I found that
1. the try_receive / try_send will block python when the mq is empty / full.
2. when I use the wrapped message queue in one Python thread, any
other Python thread would be blocked and won't execute.
I'd appreciate a lot for your help!
Below is my C++ wrapping codes.
===============================================
class message_queue {
public:
message_queue(unsigned int, const char*, size_t, size_t);
~message_queue();
void send(boost::python::str str_buffer, size_t m_size);
void try_send(boost::python::str str_buffer, size_t m_size);
boost::python::str receive(size_t m_size);
boost::python::str try_receive(size_t m_size);
private:
bi::message_queue* p_message_queue;
};
message_queue::message_queue(unsigned int flag, const char* mq_name,
size_t mq_length = 1, size_t m_size = 1) {
switch(flag) {
case 0:
p_message_queue = new bi::message_queue(bi::create_only, mq_name,
mq_length, m_size);
break;
case 1:
p_message_queue = new bi::message_queue(bi::open_or_create,
mq_name, mq_length, m_size);
break;
case 2:
p_message_queue = new bi::message_queue(bi::open_only, mq_name);
break;
}
}
message_queue::~message_queue() {
delete p_message_queue;
}
void message_queue::send(boost::python::str str_buffer, size_t m_size) {
assert(m_size ==
boost::python::extract<size_t>(str_buffer.attr("__len__")()));
const char* buffer = boost::python::extract<const char*>(str_buffer);
p_message_queue->send(buffer, m_size, 0);
}
void message_queue::try_send(boost::python::str str_buffer, size_t m_size) {
assert(m_size ==
boost::python::extract<size_t>(str_buffer.attr("__len__")()));
const char* buffer = boost::python::extract<const char*>(str_buffer);
p_message_queue->try_send(buffer, m_size, 0);
return;
}
boost::python::str message_queue::receive(size_t m_size) {
char* buffer = new char[m_size];
bi::message_queue::size_type recvd_size;
unsigned int priority;
p_message_queue->receive(buffer, m_size, recvd_size, priority);
return boost::python::str(buffer, m_size);
}
boost::python::str message_queue::try_receive(size_t m_size) {
char* buffer = new char[m_size];
bi::message_queue::size_type recvd_size;
unsigned int priority;
p_message_queue->try_receive(buffer, m_size, recvd_size, priority);
return boost::python::str(buffer, m_size);
}
bool shared_memory_object_remove(const char* shm_name) {
return bi::shared_memory_object::remove(shm_name);
}
BOOST_PYTHON_MODULE(boost_ipc) {
using namespace boost::python;
class_<message_queue>("message_queue", init<unsigned int, const
char*, optional<size_t, size_t> >())
.def("send", &message_queue::send)
.def("receive", &message_queue::receive)
.def("try_send", &message_queue::send)
.def("try_receive", &message_queue::receive);
def("message_queue_remove", message_queue_remove);
scope().attr("O_CREATE_ONLY") = 0;
scope().attr("O_OPEN_OR_CREATE") = 1;
scope().attr("O_OPEN_ONLY") = 2;
}
===========================================
Below is the Python Script that will block on try_receive
function.
===========================================
#!/usr/bin/python
import boost_ipc
boost_ipc.message_queue_remove("test_mq")
mq1 = boost_ipc.message_queue(boost_ipc.O_CREATE_ONLY, "test_mq", 1, 5)
mq2 = boost_ipc.message_queue(boost_ipc.O_OPEN_ONLY, "test_mq")
mq1.try_send("hello", 5)
print mq2.receive(5)
print mq2.try_receive(5)
More information about the Cplusplus-sig
mailing list