linux 当主机IP地址改变时,如何退出无休止的zmq_poll?

zmeyuzjn  于 2022-11-28  发布在  Linux
关注(0)|答案(2)|浏览(145)

我用zmq_poll()写了一个zmq代理,它有3个前端和3个后端,超时为-1,这使得它没有尽头。前端套接字使用面向连接的tcp://-传输类,并且是zmq_bind(),与主机IP地址上的tcp-端口相关联,如tcp://192.168.1.1:1000
当我的主机的IP地址改变时,有没有办法打破无休止的zmq_poll( ..., ..., -1 )循环?

while(1) {
    zmq_msg_t message;
    zmq_pollitem_t items [] = {
            { frontend1, 0, ZMQ_POLLIN, 0 },
            { backend1,  0, ZMQ_POLLIN, 0 },
    };
    zmq_poll (items, 2, -1);
    if(items[0].revents & ZMQ_POLLIN) {
     ...
    }
    if(items[1].revents & ZMQ_POLLIN) {
     ...
    }
}

我曾尝试轮询ZMQ_POLLIN | ZMQ_POLLERR之类的事件,但当我手动更改主机的IP地址时,它不会从对zmq_poll( ..., ..., -1 )的调用中返回。

x33g5p2x

x33g5p2x1#

    • 问**:"当主机IP地址更改时,如何退出无尽的zmq_poll?"

最好的方法是永远不要允许一段代码让你失去对工作流的控制。
左、右;
接受一个准则,你意识到自己变得无能为力,最终依赖于一些(可能永远不会出现)外部刺激,嗯,一个人不需要是阿波罗制导计算机设计师,但他永远不敢把这样的代码投入生产。愿意上一堂关键系统设计课吗?请随意阅读Ms. Margaret HAMILTON提供的任何内容,这是NASA阿波罗计划的英雄,她拯救了机组人员免于撞向月球表面。终身的教训来自于这位聪明勇敢的女士60年前已经表演过的精湛技艺。

最佳方法:

设计一个自我适应的机会(在头脑中有一个达尔文)。
声明zmq_poll()的所有用例在空闲周期中都有一些与稳定性相关的控制循环延迟(其中没有事件被标记),对于已知的控制环路稳定性阈值,假设100 ms具有大约~ 10 Hz的选通脉冲,或者10 ms具有大约~ 100 Hz的选通脉冲,并使用空闲循环时间来检测代码中任何和所有此类重要更改并发出软信号,这样就有机会在每次事件时有意识地进行自适应。
作为良好设计实践的一个例子,对改变的接口地址的自适应(一个实时系统手动IP地址改变就是这样的一个例子)也应该停用所有到目前为止活动的(现在死的).bind()-s,因为这些可能会干扰一些基于循环和公平队列的Socket()-示例的方法,现在潜在地在聋端无限等待等。)
在这里,这样的对策可能是无穷无尽的,但是设计非阻塞、自适应代码的哲学是相同的。
假设问题肯定他们会来,我们唯一不知道的是,当他们来,从哪个方向和多久,我们将不得不费心去应付他们。
剩下的是你的:o)

qyswt5oh

qyswt5oh2#

您需要的是一种控制机制,当需要重新配置轮询项时,它会使zmq_poll()返回。
首先创建一个轮询控制套接字:

void *poll_ctrl = zmq_socket (context, ZMQ_PAIR);
zmq_bind (poll_ctrl, "inproc://poll_control");

现在修改您的轮询循环以包含poll_ctrl套接字:

while(1) {
    zmq_msg_t message;
    zmq_pollitem_t items [] = {
            { frontend1, 0, ZMQ_POLLIN, 0 },
            { backend1,  0, ZMQ_POLLIN, 0 },
            { poll_ctrl, 0, ZMQ_POLLIN, 0 },
    };
    zmq_poll (items, 3, -1);
    if(items[0].revents & ZMQ_POLLIN) {
     ...
    }
    if(items[1].revents & ZMQ_POLLIN) {
     ...
    }
    if(items[2].revents & ZMQ_POLLIN) {
     // read command and loop
     char cmd [4] = { 0 };
     int size = zmq_recv (items[2].socket, cmd, sizeof(cmd) - 1, 0);
     if (size > 0)
      buffer[size < sizeof(cmd) ? size : sizeof(cmd) - 1] = '\0';
     // more processing can be done here based on command if necessary
    }
}

现在创建一个函数来触发zmq_poll()在ip改变时返回:

void reconfigure_poll() {
    void *ctrl = zmq_socket (context, ZMQ_PAIR);
    zmq_connect (ctrl, "inproc://poll_control");
    zmq_send (ctrl, "CFG", 3, );
    zmq_close (ctrl);
}

该机制是线程安全的。

相关问题