【问题标题】:jeromq: closing context failsjeromq:关闭上下文失败
【发布时间】:2013-07-23 18:26:52
【问题描述】:

编辑:自己解决了,见下文(虽然我不确定我是否在这里偶然发现了一个错误)

使用下面简单的 hello-world request-reply 示例,在程序结束时关闭上下文失败:要么它只是挂在ctx.close(),要么抛出以下异常:

Exception in thread "reaper-1" java.lang.NullPointerException
    at zmq.Ctx.destroy_socket(Ctx.java:327)
    at zmq.ZObject.destroy_socket(ZObject.java:144)
    at zmq.SocketBase.check_destroy(SocketBase.java:938)
    at zmq.SocketBase.start_reaping(SocketBase.java:753)
    at zmq.Reaper.process_reap(Reaper.java:133)
    at zmq.ZObject.process_command(ZObject.java:114)
    at zmq.Reaper.in_event(Reaper.java:90)
    at zmq.Poller.run(Poller.java:233)
    at java.lang.Thread.run(Thread.java:724)

无论哪种方式,程序都不会停止。

这是代码(请注意,套接字在创建它们的线程中都是关闭的):

import org.zeromq.ZMQ;
import org.zeromq.ZContext;

public class App {
    public static void main(String[] args) throws InterruptedException {
        final ZContext ctx = new ZContext();

        final Thread t1 = new Thread() {
            @Override
            public void run() {
                ZMQ.Socket socket = ctx.createSocket(ZMQ.REQ);
                socket.connect("inproc://test");
                System.err.format("[Thread %s] socket connected%n", Thread.currentThread().getId());
                socket.send("hello");
                System.err.format("[Thread %s] hello sent%n", Thread.currentThread().getId());
                String result = socket.recvStr();
                System.err.format("[Thread %s] received response '%s'%n", Thread.currentThread()
                        .getId(), result);
                socket.close();
                System.err.format("[Thread %s] socket closed%n", Thread.currentThread().getId());
                ctx.destroySocket(socket);
                System.err.format("[Thread %s] socket destroyed%n", Thread.currentThread().getId());
            }
        };
//      t1.start();

        final Thread t2 = new Thread() {
            @Override
            public void run() {
                ZMQ.Socket socket = ctx.createSocket(ZMQ.REP);
                socket.setLinger(10000);
                socket.bind("inproc://test");
                System.err.format("                    [Thread %s] socket bound%n", Thread.currentThread().getId());
                String request = socket.recvStr();
                assert request == "hello";
                System.err.format("                    [Thread %s] received request '%s'%n", Thread.currentThread()
                        .getId(), request);
                socket.send("world");
                socket.close();
                System.err.format("                    [Thread %s] socket closed%n", Thread.currentThread().getId());
                ctx.destroySocket(socket);
                System.err.format("                    [Thread %s] socket destroyed%n", Thread.currentThread().getId());
            }
        };
        t2.start();
        Thread.sleep(2000);
        t1.start();

        System.err.println("waiting on the threads to finish...");
        t1.join();
        t2.join();

        System.err.println("closing context...");
        ctx.close();
    }
}

编辑:已解决

事实证明socket.close() 不起作用,而仅ctx.destroySocket(socket) 就足够了(它还会关闭套接字)。所以删除socket.close() 解决了这个问题。这是一个错误吗?

【问题讨论】:

    标签: java zeromq jeromq


    【解决方案1】:

    有同样的问题;这不是一个错误,使用一个或另一个,而不是两者,但使用ZContext 方法,它们更有效。

    close() 显式关闭套接字,因此随后调用 ctx.destroySocket() 会引发该异常。如果您需要关闭套接字,请使用ctx.destroySocket(),根本不要使用close(),并且始终使用ctx.destroy() 关闭上下文,然后再优雅地关闭和退出,它将自动关闭从该上下文创建的所有套接字.

    【讨论】:

      【解决方案2】:

      我也遇到了类似的问题,在网上浏览了一番后,我在 JeroMQ(ZMQ 的 java 实现)的 Github 站点上找到了有关相关主题的讨论。

      https://github.com/zeromq/jeromq/issues/40

      ZMQ.Context 似乎是低级 API 的一部分,而 ZContext 是高级 API。因此,context.close 不应该与 ZContext 一起使用,而 ctx.destroySocket() 应该。而且我确信还有许多其他类似的问题值得人们了解。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-19
        • 2015-01-23
        • 1970-01-01
        • 2013-07-02
        • 1970-01-01
        • 1970-01-01
        • 2010-12-17
        • 2011-07-13
        相关资源
        最近更新 更多