首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >jeromq:关闭上下文失败

jeromq:关闭上下文失败
EN

Stack Overflow用户
提问于 2013-07-24 10:24:13
回答 2查看 2.6K关注 0票数 8

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

使用下面简单的hello-world请求-应答示例,在程序结束时关闭上下文将失败:要么简单挂起ctx.close(),要么抛出以下异常:

代码语言:javascript
复制
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)

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

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

代码语言:javascript
复制
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()解决了这个问题。这是个虫子吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-24 16:39:15

有同样的问题;它不是一个bug,使用一个或另一个,而不是同时使用,但是使用ZContext方法,它们更有效率。

close()显式地关闭套接字,因此调用ctx.destroySocket()之后会抛出该异常。如果您需要关闭套接字,使用ctx.destroySocket(),根本不使用close(),并且始终在关闭和优雅退出之前使用ctx.destroy()关闭上下文,它将自动关闭从该上下文创建的任何套接字。

票数 4
EN

Stack Overflow用户

发布于 2013-11-25 14:45:58

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

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

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17831295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档