繁体   English   中英

ZeroMQ推/拉

[英]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;
        }
    }  
}
  1. 将每个cpp编译为其自己的exe。
  2. 启动两个exe(启动顺序无关)

如果定义了ENABLE_PROBLEM

  • 发布者:(EMPTY提示)
  • 订阅者:“正在接收...”,然后您必须杀死两个进程,因为它们已挂起...

如果ENABLE_PROBLEM

  • 发布者:“已接收:同步”“已发送3个字节”
  • 订阅者:“正在接收...”“结束”

EDIT#1 2014-08-11:原始帖子已更改,但未显示任何修订

目标是什么?

出于所有应有的尊重,很难从上面的三个SLOC中分离出目标并模拟任何通过/失败测试以验证目标。

因此,让我们逐步开始。

那里使用什么ZMQ基元?

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 ------------------------------------------------
...

部署了哪些ZMQ上下文创建/终止生命周期策略?

TBD

post-EDIT#1 :nb:ZMQ_LINGER会影响资源的.close() ,这可能会在ZMQ_Context终止出现之前发生。 (并可能阻止...伤害...)

关于“ ZMQ_LINGER何时真正重要?”的注释

一旦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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM