[英]EAGAIN in ZMQ extended request reply
我正在嘗試在C ++中創建REQ <->路由器<->經銷商<-> REP通信。 子進程綁定路由器和經銷商,路由器和經銷商之間的代理,將REP連接到經銷商,並等待帶有zmq_recv的消息。
父進程將REQ連接到路由器並嘗試發送消息,但是我zmq_send error in parent: Resource temporarily unavailable
遇到zmq_send error in parent: Resource temporarily unavailable
(這是EAGAIN
)。 根據zmq_send docs, EAGAIN
表示:
已請求非阻止模式,並且此刻無法發送消息。
但是,由於在子進程中收到了該消息,因此確實會發送該消息。 為什么它返回那個errno?
這是MCVE :
#include <zmq.h>
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <assert.h>
#include <thread>
#include <stdio.h>
int main() {
char connect_path[35];
int rc;
int msg;
pid_t child_pid = fork();
if (child_pid == 0) {
// Child
void* child_context = zmq_ctx_new ();
if (child_context == NULL) {
std::cerr << "\nChild context error\n";
}
void* router = zmq_socket(child_context, ZMQ_ROUTER);
if (router == NULL) {
perror("zmq_socket of type router error");
}
char bind_path[35];
snprintf(bind_path, sizeof(bind_path), "ipc:///tmp/zmqtest%d-router", getpid());
rc = zmq_bind(router, bind_path);
assert (rc == 0);
void* dealer = zmq_socket(child_context, ZMQ_DEALER);
if (dealer == NULL) {
perror("zmq_socket of type dealer error");
}
snprintf(bind_path, sizeof(bind_path), "ipc:///tmp/zmqtest%d-dealer", getpid());
rc = zmq_bind(dealer, bind_path);
assert (rc == 0);
std::thread z_proxy (zmq_proxy, router, dealer, nullptr);
z_proxy.detach();
void* rep_socket = zmq_socket (child_context, ZMQ_REP);
if (rep_socket == NULL) {
perror("zmq_socket of type rep error");
}
snprintf(connect_path, sizeof(connect_path), "ipc:///tmp/zmqtest%d-dealer", getpid());
rc = zmq_connect(rep_socket, connect_path);
assert (rc == 0);
while(1) {
if (zmq_recv (rep_socket, &msg, sizeof(msg), 0) != 0) {
perror("zmq_recv error");
}
printf("\nReceived msg %d in process %d\n", msg, getpid());
break;
}
if (zmq_close(rep_socket) != 0) {
perror("zmq_close of rep_socket in child error");
}
if (zmq_ctx_term(child_context) != 0) {
perror("zmq_ctx_term of child_context error");
}
} else {
// Parent
sleep(1);
void* parent_context = zmq_ctx_new ();
if (parent_context == NULL) {
std::cerr << "\nParent ctx error\n";
}
void* req_socket = zmq_socket (parent_context, ZMQ_REQ);
if (req_socket == NULL) {
perror("zmq_socket of type req error in parent");
}
snprintf(connect_path, sizeof(connect_path), "ipc:///tmp/zmqtest%d-router", child_pid);
rc = zmq_connect(req_socket, connect_path);
assert (rc == 0);
msg = 30;
if (zmq_send (req_socket, &msg, sizeof(msg), 0) != 0) {
perror("zmq_send error in parent");
}
if (zmq_close(req_socket) != 0) {
perror("zmq_close of req_socket in parent error");
}
if (zmq_ctx_term(parent_context) != 0) {
perror("zmq_ctx_term of parent_context error");
}
}
}
好吧,作為最低限度,應該首先進行這種test-en-Queueing:
rc = zmq_send ( req_socket, "A_TEST_BLOCK", 12, ZMQ_DONTWAIT );
printf ( "INF: zmq_send ( req_socket, "A_TEST_BLOCK", 12, ZMQ_DONTWAIT )\nZMQ: returned rc == %d\nZMQ: zmq_errno ~ %s\n",
rc,
zmq_strerror ( zmq_errno() )
);
。
接下來,如果有任何“遺漏”的鏡頭,則錯誤分析可能會建議潛在的原因
( 且僅當parent_ctx
確實拒絕甚至接受來自最簡單的zmq_send()
調用的數據到其內部排隊設施中的數據時, zmq_send()
這樣做的明確理由 )。
否則,我們一無所知(並且ZMQ_DONTWAIT
標志不是這里的原因)。
INF: zmq_send ( req_socket, 'A_TEST_BLOCK', 12, ZMQ_DONTWAIT )
ZMQ: returned rc == 12
ZMQ: zmq_errno ~ Resource temporarily unavailable
根據文檔,測試已確認:
如果成功 ,
zmq_send()
函數應返回消息中的字節數。
因此,讓我們進一步深入:
int major, minor, patch;
zmq_version ( &major, &minor, &patch );
printf ( "INF: current ØMQ version is %d.%d.%d\nZMQ: zmq_errno ~ %s\n",
major, minor, patch,
zmq_strerror ( zmq_errno() )
);
如果最新的API更新不符合已發布的API規范,請記錄以下事件:
printf ( "EXPECT( NO ERROR, ON START ): zmq_errno ~ %s\n",
zmq_strerror ( zmq_errno() )
);
printf ( "EXPECT( <major>.<minor>.<patch> ): zmq_version ~\n" );
int major, minor, patch
zmq_version ( &major, &minor, &patch );
printf ( "INF: current ØMQ version is %d.%d.%d\nZMQ: zmq_errno ~ %s\n",
major, minor, patch
)
printf ( "EXPECT( NO ERROR ): zmq_errno ~ %s\n",
zmq_strerror ( zmq_errno() )
);
printf ( "EXPECT( NO ERROR ): zmq_send() ~ %s\n" );
rc = zmq_send ( req_socket, "A_TEST_BLOCK", 12, ZMQ_DONTWAIT );
printf ( "INF: zmq_send ( req_socket, "A_TEST_BLOCK", 12, ZMQ_DONTWAIT )\nZMQ: returned rc == %d which ouhgt be == 12, is it?\n",
rc
);
printf ( "EXPECT( NO ERROR ): zmq_errno ~ %s\n",
zmq_strerror ( zmq_errno() )
);
如果出現意外結果,請隨時提出問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.