簡體   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