編集:自分で解決しました。以下を参照してください(ただし、ここでバグに遭遇したかどうかはわかりません)
以下の単純な 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)
いずれにせよ、プログラムは停止しません。
コードは次のとおりです (ソケットを作成するスレッド内で両方のソケットが閉じられていることに注意してください)。
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()
すると問題が解決します。これはバグですか?