Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java jeromq:关闭上下文失败 编辑:我自己解决了,见下文(尽管我不确定我是否在这里偶然发现了一个bug)_Java_Zeromq_Jeromq - Fatal编程技术网

Java jeromq:关闭上下文失败 编辑:我自己解决了,见下文(尽管我不确定我是否在这里偶然发现了一个bug)

Java jeromq:关闭上下文失败 编辑:我自己解决了,见下文(尽管我不确定我是否在这里偶然发现了一个bug),java,zeromq,jeromq,Java,Zeromq,Jeromq,使用下面简单的hello world请求-应答示例,在程序结束时关闭上下文失败:要么挂起在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.che

使用下面简单的hello world请求-应答示例,在程序结束时关闭上下文失败:要么挂起在
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)
无论如何,程序都不会停止

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

编辑:已解决
结果是,
socket.close()
不起作用,而
ctx.destroySocket(socket)
本身就足够了(它也会关闭套接字)。因此,移除
socket.close()
解决了这个问题。这是一个bug吗?

也有同样的问题;这不是一个bug,可以使用其中一个,也可以使用两个,但是使用
ZContext
方法,它们更有效


close()
显式关闭套接字,因此随后调用
ctx.destroySocket()
会引发该异常。如果需要关闭套接字,请使用
ctx.destroySocket()
,完全不要使用
close()
,并始终使用
ctx.destroy()
在关闭并正常退出之前关闭上下文,它将自动关闭从该上下文创建的任何套接字。

我也有类似的问题,在一些冲浪之后,我在JeroMQ(ZMQ的java实现)的Github站点上发现了一个关于相关主题的讨论

似乎ZMQ.Context是低级API的一部分,而ZContext是高级API。因此,context.close不应与ZContext一起使用,而ctx.destroySocket()应与ZContext一起使用。我相信还有很多其他类似的问题需要我们去了解

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();
    }
}