提升进程间message_queue和分叉
boost interprocess message_queue and fork
我正在尝试使用来自 boost 进程间库的消息队列与分叉子进程进行通信。当子进程调用收到时,它会导致异常并显示消息
提升::interprocess_exception::library_error
我在 Debian 9 x64 上使用 GCC 6.3。
#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;
}
另外,在子进程中是否需要重新打开父进程创建的消息队列?我尝试了两种方式,但都没有奏效。我在接收时收到相同的异常。
问题是您的接收缓冲区小于max_msg_size
。假设 4 字节整数,这应该可以工作:
int num[8];
mq.receive(num, sizeof(num), bytes, priority);
std::cout << *num << std::endl;
此外,我认为没有理由对实际的队列实例进行快速和松散的游戏。只需按进程创建它:
#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);
}
}
}
相关文章:
- 为什么这个 std::queue/指向结构的指针列表直到 List.Size() == 0 才释放内存?
- 将参数打包的参数传递到 std::queue 中,以便稍后使用不同的函数调用
- C++ queue.front();为什么不从第一个元素开始呢?
- 提升进程间message_queue和分叉
- 我可以擦除 std::queue 中间的节点吗?
- 播种随机数生成器以使用分叉的好方法是什么?
- 如何在有限的分叉数量下运行类似shell的管道任务
- 从执事创建一个分叉进程
- 拿着锁时分叉
- 获取大小时是否必须锁定 std::queue?
- 分叉后对全局资源的所有权
- 为什么我会收到"invalid conversion from 'Queue*/Stack*' to 'int'"错误消息?
- 销毁 std::queue 会导致内存错误
- 同时分叉 100 个进程,有时有些进程会变成僵尸
- 使用管道从 STDIN 读取分叉进程时出现问题
- 子进程在分叉和执行后变得失效
- 如何将一个 std::queue 的内容附加到另一个
- 分叉和杀戮 C++崩溃了 ubuntu
- 使用元素加载 std::queue<uint8_t*> 的更有效方法?
- 为什么 std::queue 没有实现 insert() 而 std::d eque 实现了?