我在本机方法中有一个线程阻塞,这反过来阻塞并等待linux read
函数(include <fcntl.h>
)返回:
int n = read(g_fd, dest, len);
其中g_fd
是串行端口的文件描述符
在这种情况下,如何“中断”阻塞线程?
对于遇到相同问题的人编辑:
1.应避免使用无限阻塞IO。没有明显的方法可以打断它
2. @Rohit Karlupia的答案应该有效
3.一种hackish方式是在Java和本机代码之间共享文件描述符,如本文所示:http://www.kfu.com/~nsayer/Java/jni-filedesc.html然后我们可以使用FileDescriptor
答案 0 :(得分:0)
不确定这是否适合您,但在类似的情况下(使用 socket 读取)我使用关闭套接字作为“中断”。然后read()调用可以返回。在我的情况下,它通过抛出一些我捕获并处理中断的异常来“返回”。即。
public int myRead(g_fd, dest, len) {
try {
return read(g_fd, dest, len);
}
catch (SomeIOExceptionIForgetWhatItWas ex) {
throw new InterruptedException();
}
}
您可能还需要检查-1(或其他一些特殊代码)。
答案 1 :(得分:0)
Java支持可中断的IO,但这只适用于java IO类,而不适用于通过本机代码直接调用的系统调用。 Java确实有用于与串口通信的软件包。看看你是否可以使用它们而不是本机代码。
如果本机代码不可避免,那么你可以做这样的事情。 - 以非阻塞模式打开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;
}
}
}
}
}