[英]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.