Java 线程在本机方法中阻塞等待 I/O 完成
我在本机方法中有一个线程阻塞,该线程又阻塞并等待 linux read
函数 (include
) 返回:
int n = read(g_fd, dest, len);
其中 < code>g_fd 是串口的文件描述符
这种情况下,如何“中断”阻塞线程呢?
对于有同样问题的人编辑:
1. 应避免无限阻塞IO。没有明显的方法可以中断它
2. @Rohit Karlupia 的答案应该有效
3. 一种 hackish 方法是在 Java 和本机代码之间共享文件描述符,如本文所示: http://www.kfu.com/~nsayer/Java/jni-filedesc.html 然后我们可以使用FileDescriptor
创建可中断的Java IO流对象
I have a Thread blocking in a native method, which in turn is blocking and waiting for a linux read
function (include <fcntl.h>
) to return:
int n = read(g_fd, dest, len);
where g_fd
is the file descriptor of a serial port
In this situation, how to "interrupt" the blocking thread?
EDIT for someone who has the same problem:
1. Infinite blocking IO should be avoid. There is no apparent way to interrupt it
2. @Rohit Karlupia's answer should work
3. A hackish way is to share file descriptor between Java and native code, as this article demonstrated: http://www.kfu.com/~nsayer/Java/jni-filedesc.html Then we can make interruptable Java IO stream objects with the FileDescriptor
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不确定这是否适合您,但在类似的情况下(使用套接字读取)我诉诸关闭套接字作为“中断”。然后 read() 调用可能会返回。就我而言,它通过抛出一些异常“返回”,我捕获并处理了一个中断。即
您可能还必须检查 -1 (或其他一些特殊代码)。
Not sure if this will work for you, but in a similar case (with a socket read) I resorted to closing the socket as an "interrupt". The read() call may then return. In my case it "returned" by throwing some exception which I caught and treated an an interrupt. i.e.
You might also have to check for a -1 (or some other special code) as well.
Java 支持可中断 IO,但这仅适用于 java IO 类,不适用于通过本机代码直接调用的系统调用。 Java 确实有用于与串行端口通信的包。看看是否可以使用它们来代替本机代码。
如果本机代码是不可避免的,那么你可以这样做。
- 以非阻塞模式打开fd
- 要模拟阻塞行为,请将 select 与您在上面创建的单个 fd 一起使用
- 不要在选择中使用无限超时,而是使用带有循环的每秒超时
- 要中断线程,您可以从其他线程设置一个标志,可以通过“包装器代码”检查该标志,以便在选择超时后每秒读取一次。
Java supports interruptible IO, but that would work only with java IO classes and not the system calls directly invoked via native code. Java does have packages for talking to serial port. See if you could use them instead of native code.
If native code is unavoidable, then you could do something like this.
- open the fd in non-blocking mode
- to simulate blocking behavior, use select with the single fd you created above
- instead of using infinite timeout in select, use say per second timeout with a loop
- to interrupt the thread, you could set a flag from other thread, which can be checked by the "wrapper code" for read every second it comes out of the select timeout.