【发布时间】:2019-05-01 10:26:32
【问题描述】:
我正在创建一个应用程序,其中多个进程通过增强消息队列进行通信。队列是使用消息队列构造函数创建的
message_queue(open_or_create, name, max_num_msg, max_msg_size);
我对所有进程中的所有队列都使用 open_or_create,因为没有指定必须创建队列的顺序。
max_num_msg = 200 和 max_msg_size = 500000。
现在创建似乎一切正常,但是在通过队列发送消息一段时间后,由于读取访问冲突,我突然崩溃了。做了一些调试,我找到了message_queue.hpp 中do_send 的定义,其中获取了一个空的消息头来写入消息
//Insert the first free message in the priority queue
ipcdetail::msg_hdr_t<VoidPointer> &free_msg_hdr = p_hdr->queue_free_msg(priority);
//Sanity check, free msgs are always cleaned when received
BOOST_ASSERT(free_msg_hdr.priority == 0);
BOOST_ASSERT(free_msg_hdr.len == 0);
错误发生在free_msg_hdr.priority == 0,因为free_msg_hdr 的地址不指向可读位置。
做更多的研究发现,在队列的创建中,
template<class VoidPointer>
inline message_queue_t<VoidPointer>::message_queue_t(open_or_create_t,
const char *name,
size_type max_num_msg,
size_type max_msg_size,
const permissions &perm)
//Create shared memory and execute functor atomically
: m_shmem(open_or_create,
name,
get_mem_size(max_msg_size, max_num_msg),
read_write,
static_cast<void*>(0),
//Prepare initialization functor
ipcdetail::msg_queue_initialization_func_t<VoidPointer>(max_num_msg, max_msg_size),
perm)
{}
创建的共享内存对象m_shmem 的大小太小,无法容纳 200 条大小为 500000 的消息。这解释了为什么崩溃有点不可预测,因为仍然可以访问一小部分内存,因此需要一些时间不小心进入人迹罕至的部分。但是,我仍然不知道为什么会这样。查看函数get_mem_size(max_msg_size, max_num_msg) 它返回正确的大小,但创建后大小更小。如果我然后重新创建相同的队列,它通常会得到正确的大小,并且我永远不会遇到任何异常。如果有人知道为什么会发生这种情况,或者对如何进一步调试此问题提出建议,将不胜感激。
我应该提一下,该应用程序是用 32 位 Visual C++ 编译并在 Windows 10 上运行的。Windows 共享内存实现会导致这样的问题吗?
【问题讨论】:
标签: memory boost message-queue interprocess