如何在JeroMQ套接字上中断对.read()方法的调用?

时间:2018-03-18 17:19:28

标签: java zeromq jeromq

在我的代码中,我有一个等待ZeroMQ端点上的事件的线程,它的主循环看起来类似于:

while (externalCondition) {
  byte[] bytes = subscriber.recv(0);
  // Do things
}

问题是我不知道如何中断对 .recv() 方法的调用,如果我想退出该帖子(例如因为我想要关闭)应用程序)。

我试图打断线程,但这似乎不起作用。

1 个答案:

答案 0 :(得分:1)

欢迎使用ZeroMQ和分布式系统架构。

没有廉价的方法来打断这样的呼叫(除了残酷的一个),但是

有一种简单的方法可以重新考虑这个想法,因为它可以在分布式系统领域中运行:

/* THIS CODE IS NOT A COPY+PASTE SYNDROME-PROOF, BUT HAS THE DESIGN IDEA CLEAR,
        CODE IS NOT A READY TO RUN, AS THE TARGET LANGUAGE
                AND THE ACTUAL ZeroMQ BINDING / VERSION
                                      WILL DECIDE ON FURTHER DETAILS TO CODE IN
   */
while ( True ) { // -[NEVER-BLOCK]----------- aSoftRealTIME-control-loop-<body>--

   bool ec = externalCondition;
   int  rc = subscriber.poll( someSoftRealTimeDELAY_in_ms );

   if ( ec
      & rc == 0
        ){
        //--------------------------------------------------
       // DO NOTHING, AS THERE IS NOTHING TO WORK ON
      //  or sleep, or
     //   DO ANY SoftRealTime-controlled / yet interruptible
    //           maintenance workpackage(s)
   //-------------------------------------------------------
   }
   if ( !ec ){
        break; // __________________________ J.I.T. / JMP / RET __^
   }
   if (  rc < 0 ){
               // ZeroMQ .poll() Error Analysis & Error Recovery
   }
   if (  rc > 0 ){

               // ZeroMQ has a thing to indeed .recv(), so read it:
         byte[] bytes = subscriber.recv( zmq.DONTWAIT );

         ...   // DO things ... on bytes ...
   }
}  // ---------------[NEVER-BLOCK]----------- aSoftRealTIME-control-loop-<body>--

Nota bene

虽然这句话对你来说可能是一个相当知名的主题,如果你已经熟悉ZeroMQ内部性和各种默认值,但是,我也在这里提到它,因为并非所有类型的读者都有如此深刻的ZeroMQ实践

上面使用的可扩展正式通信模式的 SUB -side有一个黑暗面。除非有人明确地“订阅”某些报纸和/或杂志,否则没有任何东西进入一个SUB - 侧邮箱,根本没有任何东西可以送达,因为“送货服务”还没有收到任何订阅你告诉他们你想要什么(接收)和阅读

所以,总是不要忘记提交这样一个

的电话

subscriber.setsockopt( aSubject_What_To_Subscribe_To_Indeed_Receive_STRING );

没有这样做,永远不会.recv()一个字节。

  

感谢。 什么是“野蛮”? - Alessandro Polverini 23 hours ago

好吧,ZeroMQ原生API,截至2018年第一季度允许一种相当残酷的方式实现对 .recv() 方法的阻止调用的强制中断 - 调用 { {1}} - 所以,当仅仅要求几张纸时,它更像是一个“拆迁人”...确实那样,还有更多预先如果不是无限制地(如果没有保护你所有的 <Context>.term() - 实例保护你native-API,具有立即配置的 Socket (因为本机API 2.1 + ~4。(?)已发布默认的默认更改...相应的语言绑定/包装器版本不同采用,所以不能一般性地参考并最好检查实例化时发布的 .setsockopt( zmq.LINGER, 1 ) - 暴露方法,以查看每个事件的反应性:o))。

使用 .getLinger() 方法调用类似大规模杀伤性武器的方法,在这些情况下,.term() - 实例不会等待(不确定,如果不是无限的话)通过 Socket -instance属性,取消internal-FSA并退出仍然被阻止的 zmq.LINGER -s并返回代码执行控件 - 你的“拆迁人”的路径 - 控制:o)

可行,但有点刺耳,不是吗?