[英]ZeroMQ PUSH/PULL
zmq
某些部分行为zmq
。
我正在使用VS2013和zmq 3.2.4。 为了不“丢掉”我的pubsub框架中的消息,[我认为这是设计缺陷。 我应该能够先启动订阅者,然后再启动发布者,并且我应该收到所有消息。]我必须使发布者与订阅者同步,例如la durapub / durasub等。我使用在zeromq中找到的durasub.cpp和durapub.cpp示例指南。 如果我按原样使用示例,则系统可以正常运行。
如果现在在ZMQ_PUSH
中的ZMQ_PUSH周围添加范围界定括号
{
zmq::socket_t sync (context, ZMQ_PUSH);
sync.connect(syncstr.c_str());
s_send (sync, "sync");
}
系统停止工作。 匹配的“ ZMQ_PULL”信号永远不会达到durapub.cpp中的应用程序级别。
我已经逐步完成了C ++包装程序,以检查zmq_close
的返回值,一切都很好。 就ZMQ而言,它已将消息传递到端点。 希望我做了一些明显愚蠢的事情?
还有更多。 的加法
std::this_thread::sleep_for(std::chrono::milliseconds(1));
允许系统(即pub / sub)再次开始工作。 因此,这显然是一种竞争条件,大概是因为它破坏了套接字而在收割线程中。
更多挖掘。 我认为LIBZMQ-179也涉及到该问题。
EDIT#2 2014-08-13 03:00 [UTC + 0000]
Publisher.cpp:
#include <zmq.hpp>
#include <zhelpers.hpp>
#include <string>
int main (int argc, char *argv[])
{
zmq::context_t context(1);
std::string bind_point("tcp://*:5555");
std::string sync_bind("tcp://*:5554");
zmq::socket_t sync(context, ZMQ_PULL);
sync.bind(sync_bind.c_str());
// We send updates via this socket
zmq::socket_t publisher(context, ZMQ_PUB);
publisher.bind(bind_point.c_str());
// Wait for synchronization request
std::string tmp = s_recv (sync);
std::cout << "Recieved: " << tmp << std::endl;
int numbytessent = s_send (publisher, "END");
std::cout << numbytessent << "bytes sent" << std::endl;
}
Subscriber.cpp
#include <zmq.hpp>
#include <zhelpers.hpp>
#include <string>
int main (int argc, char *argv[])
{
std::string connectstr("tcp://127.0.0.1:5555");
std::string syncstr("tcp://127.0.0.1:5554");
zmq::context_t context(1);
zmq::socket_t subscriber (context, ZMQ_SUB);
subscriber.setsockopt(ZMQ_SUBSCRIBE, "", 0);
subscriber.connect(connectstr.c_str());
#if ENABLE_PROBLEM
{
#endif ENABLE_PROBLEM
zmq::socket_t sync (context, ZMQ_PUSH);
sync.connect(syncstr.c_str());
s_send (sync, "sync");
#if ENABLE_PROBLEM
}
#endif ENABLE_PROBLEM
while (1)
{
std::cout << "Receiving..." << std::endl;
std::string s = s_recv (subscriber);
std::cout << s << std::endl;
if (s == "END")
{
break;
}
}
}
如果定义了ENABLE_PROBLEM
:
如果ENABLE_PROBLEM
:
EDIT#1 2014-08-11:原始帖子已更改,但未显示任何修订
出于所有应有的尊重,很难从上面的三个SLOC中分离出目标并模拟任何通过/失败测试以验证目标。
因此,让我们逐步开始。
TBD
EDIT#1之后 : ZMQ_PUSH
+ ZMQ_PULL
+(隐藏的ZMQ_PUB
+ ZMQ_SUB
...下次,而不是发布ProblemDOMAIN-context-complete源,最好通过自测用例输出进行充实:
...
// <code>-debug-isolation-framing ------------------------------------------------
std::cout << "---[Pre-test]: sync.connect(syncstr.c_str()) argument" << std::endl;
std::cout << syncstr.c_str() << std::endl;
std::cout << "---[Use/exec]: " << std::endl;
sync.connect( syncstr.c_str());
// <code>-debug-isolation-framing ------------------------------------------------
...
)
TBD
post-EDIT#1 :nb:ZMQ_LINGER会影响资源的.close()
,这可能会在ZMQ_Context终止出现之前发生。 (并可能阻止...伤害...)
一旦Context
即将终止,而发送队列还不为空,并且正在尝试处理zmq_close()
则此参数zmq_close()
。
在大多数架构(...越低延时/高性能,在微秒和纳秒数...)(共享/限制)资源设置/处置作业出现的原因有很多无论是在非常开始时, 或者在系统生命周期的尽头。 不用多说为什么,只要想象一下与所有设置/丢弃操作直接相关的开销,这些开销在几乎真实的常规操作流程中完全不可行(重复发生的次数更少...)时间系统设计。
因此,让系统进程进入最后的“整理”阶段(就在退出之前)
设置ZMQ_LINGER == 0
只会忽略< sender >队列中仍然存在的内容,并允许出现提示zmq_close()
+ zmq_term()
同样, ZMQ_LINGER == -1
会将仍悬在< 发送方 >队列中的所有内容都标记为[ 具有最大值 ]的标签,整个系统必须等待ad-infimum ,(希望是任何一个) < 接收方 >检索并在允许发生任何zmq_close()
+ zmq_term()
之前,“消耗”所有排队的消息……这可能会很长,而且完全超出了您的控制范围……
最后,如果某些< 接收器 >出现并检索入队消息,则ZMQ_LINGER > 0
成为妥协以等待定义量的[msec] -s。 但是,在给定的TimeDOMAIN里程碑上,系统前进到zmq_close()
+ zmq_term()
,以优雅地释放所有保留的资源,并根据系统设计时序限制退出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.