问题描述
我正在使用 ZeroMQ 来实现一个玩具通信协议;这是我第一次使用这个框架/库.
I'm using ZeroMQ to implement a toy communications protocol; and this is my first time using this framework/library.
现在,在我的协议中,某一方发送了多条连续的消息,所有消息的大小都相同.所以 - 我想,我会避免重新分配它们,而只是尝试用不同的内容重新填充消息数据缓冲区,例如:
Now, in my protocol, multiple consecutive messages get sent by a certain party, all of which have the same size. So - I thought, I'd avoid reallocating them, and just try to refill the message data buffer with different content, e.g.:
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 以某种方式蚕食了内存,因此我需要编写如下内容:
but on the second iteration of this loop, I get a segmentation fault; msg.data()
is not nullptr
though. It occurred to me, that maybe ZeroMQ cannibalizes the memory somehow, and thus I need to write something like:
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);
}
但我确信这会导致取消分配和重新分配.
But I'm sure this causes de-allocation and re-allocation.
那么,rebuild()
真的是必要的,还是只是我代码中的一些错误?
So, is it really the case that a rebuild()
is necessary, or could it just be some bug in my code?
注意:我使用的是 Unix 套接字,以防万一答案取决于它.
Note: I'm using Unix sockets, in case the answer depends on that somehow.
推荐答案
不,zmq::message_t
发送后不能重复使用.
首先,欢迎来到 ZeroMQ,这是一个很酷的地方,分布式系统从业者.
ZeroMQ API 非常明确地警告这些问题.成功调用 zmq_msg_send()
,引用消息有效负载,并不意味着消息本身已实际发送.
The ZeroMQ API warns about these issues quite explicitly. A successful call to zmq_msg_send()
, referencing a message-payload, does not mean that the message itself has been actually sent.
你最好试着想象调用只是将责任从你的应用程序代码转移"到ZeroMQ引擎(在工厂内部,在中实例化了一个IO线程池)Context()
-instance ...).
It's best you try to imagine that the call just "moves" the responsiblity from your application code to the ZeroMQ engine (inside the factory with a pool-of-IOthreads instantiated inside the Context()
-instance ... ).
传递给 zmq_msg_send()
的 zmq_msg_t
结构在打电话.
和下一个更好的永远不要触碰它,如上所述:o)
and next better never touch it anytime later as reported above :o)
分配器最大的生态"旁路是重用整个消息,如:
The maximum "ecological"-bypass of allocator is to re-use the whole-message, as :
如果您想将相同的消息发送到多个套接字,您必须使用(例如使用 zmq_msg_copy()
)进行复制.
复制警告...
再加一点:可以复制,但以后敢尝试修改...
A bonus warning on copying ...
plus one more raised point: may copy, but dare to try to modify it after this ...
避免在使用 zmq_msg_copy()
复制消息后修改消息内容,这样做会导致未定义的行为.如果您需要的是实际的硬拷贝,请使用 zmq_msg_init_size()
分配新消息并使用 memcpy()
复制消息内容.
永远不要直接访问 zmq_msg_t
成员,而是始终使用 zmq_msg
函数系列.
这篇关于zmq::message_t 发送后可以重复使用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!