我正在使用ZeroMQ来实现玩具通信协议;这是我第一次使用这个框架/库。
现在,在我的协议中,多个连续的消息由某一方发送,所有这些消息都具有相同的大小。所以 - 我想,我会避免重新分配它们,并且只是尝试用不同的内容重新填充消息数据缓冲区,例如:
zmq::message_t msg { fixed_common_size };
while (some_condition()) {
my_filling_routine(msg.data(), fixed_common_size);
the_socket.send(msg);
}
但是在这个循环的第二次迭代中,我得到了一个分段错误; msg.data()
不是nullptr
。我想到,也许ZeroMQ以某种方式蚕食了记忆,因此我需要写下这样的东西:
zmq::message_t msg { fixed_common_size };
char buffer[fixed_common_size];
while (some_condition()) {
my_filling_routine(buffer, fixed_common_size);
msg.rebuild(buffer, fixed_common_size);
the_socket.send(msg);
}
但我确信这会导致取消分配和重新分配。
那么,是否真的需要rebuild()
,或者它只是我代码中的一些错误?
注意:我正在使用Unix套接字,以防答案取决于某种方式。
答案 0 :(得分:1)
zmq::message_t
可以在发送后重复使用吗?
首先,欢迎来到ZeroMQ,这是一个适合distributed-system从业者的好地方。
ZeroMQ API非常明确地警告这些问题。成功调用 zmq_msg_send()
,引用消息有效负载并不意味着消息本身已实际发送。
最好试着想象一下,调用只是将责任从您的应用程序代码移动到ZeroMQ引擎(在工厂内部,{{1}内部实例化了一个IOthread池} -instance ...)。
传递给
Context()
的zmq_msg_t
结构在通话期间无效。
然后更好从不以后随时触摸它,如上所述:o)
分配器的最大“生态” - 旁路是重新使用整个 - 消息,如下:
如果您要将相同的消息发送到多个套接字,则必须使用
zmq_msg_send()
进行复制。
另外还有一个提升点:可以复制,但敢于在此之后尝试修改它......
使用
zmq_msg_copy()
复制邮件后,避免修改邮件内容,这样做可能会导致未定义的行为。如果您需要的是实际的硬拷贝,请使用zmq_msg_copy()
分配新邮件,然后使用zmq_msg_init_size()
复制邮件内容。
永远不要直接访问memcpy()
成员,而是始终使用zmq_msg_t
- 函数系列。