[英]Java thread blocking in a native method waiting for I/O to complete
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: 我在本机方法中有一个线程阻塞,而后者又阻塞并等待linux
read
函数( include <fcntl.h>
)返回:
int n = read(g_fd, dest, len);
where g_fd
is the file descriptor of a serial port 其中
g_fd
是串口的文件描述符
In this situation, how to "interrupt" the blocking thread? 在这种情况下,如何“中断”阻塞线程?
EDIT for someone who has the same problem: 编辑有同样问题的人:
1. Infinite blocking IO should be avoid. 1.应避免使用无限阻塞IO。 There is no apparent way to interrupt it
没有明显的方法可以打断它
2. @Rohit Karlupia's answer should work 2. @Rohit Karlupia的回答应该有效
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
3.一种hackish方式是在Java和本机代码之间共享文件描述符,如本文所示: http : //www.kfu.com/~nsayer/Java/jni-filedesc.html然后我们可以创建可中断的Java IO流对象使用
FileDescriptor
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.
然后read()调用可以返回。 In my case it "returned" by throwing some exception which I caught and treated an an interrupt.
在我的情况下,它通过抛出一些我捕获并处理中断的异常来“返回”。 ie
即
public int myRead(g_fd, dest, len) {
try {
return read(g_fd, dest, len);
}
catch (SomeIOExceptionIForgetWhatItWas ex) {
throw new InterruptedException();
}
}
You might also have to check for a -1 (or some other special code) as well. 您可能还需要检查-1(或其他一些特殊代码)。
Java supports interruptible IO, but that would work only with java IO classes and not the system calls directly invoked via native code. Java支持可中断的IO,但这只适用于java IO类,而不适用于通过本机代码直接调用的系统调用。 Java does have packages for talking to serial port.
Java确实有用于与串口通信的软件包。 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.
- 以非阻塞模式打开fd - 模拟阻塞行为,使用上面创建的单个fd选择 - 而不是在select中使用无限超时,使用带有循环的每秒超时 - 中断线程,你可以设置来自其他线程的标志,可以通过“包装器代码”进行检查,以便在选择超时时间内每秒读取一次。
int myread(int fd) {
FDSET fdset = ...;
while (at least one byte read or error) {
add fd to fdset
select(fdset)
if (read events) {
do real read
return;
}else {
if (timeout) {
check global/object level interrupt flag
if (set interrupt flag) {
return;
}
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.