Java 线程在 native 方法中阻塞等待 I/O 完成

标签 java multithreading java-native-interface blocking interrupt

我在 native 方法中有一个线程阻塞,该线程又阻塞并等待 linux read函数( include <fcntl.h> )返回:

int n = read(g_fd, dest, len);

哪里g_fd是串口的文件描述符

这种情况下,如何“中断”阻塞线程呢?

对于有同样问题的人编辑:

1. 应避免无限阻塞IO。没有明显的方法可以中断它

2. @Rohit Karlupia 的回答应该有效

3. 一种黑客方法是在 Java 和 native 代码之间共享文件描述符,如本文所示:http://www.kfu.com/~nsayer/Java/jni-filedesc.html然后我们可以使用FileDescriptor创建可中断的Java IO流对象。

最佳答案

Java 支持可中断 IO,但这仅适用于 Java IO 类,不适用于通过 native 代码直接调用的系统调用。 Java 确实有用于与串行端口通信的包。看看是否可以使用它们来代替 native 代码。

如果 native 代码是不可避免的,那么你可以这样做。 - 以非阻塞模式打开fd - 要模拟阻塞行为,请将 select 与您在上面创建的单个 fd 一起使用 - 不要在选择中使用无限超时,而是使用带有循环的每秒超时 - 要中断线程,您可以从其他线程设置一个标志,可以通过“包装器代码”检查该标志,以便在选择超时后每秒读取一次。

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;
             }
          }
       }
    }
}

关于Java 线程在 native 方法中阻塞等待 I/O 完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7962197/

相关文章:

c++ - 如何使用事件循环管理线程?

Java - JNI - 将 UCS-2 字符转换为 jchar(即 Java 的 char)

java - android gradle如何将构建版本传递给android mk

java - 为 JPanel 调用 repaint()

java - Spark Streaming 之后立即进行 Spark RDD 过滤器

c# - VS 2017 的任务窗口中的 "Status" "Scheduled"是什么意思?

java - java 7在某些情况下会自动使用多核吗?

java - 错误类型 3. React Native 中不存在 Activity 类 {com.project/com.project.MainActivity} (Visual studio EMulator for Android)

JAVA- Integer.parseInt( str ) 给出 NumberFormatException,输入是代表整数的 str

java - JNI 可以处理任何 dll 文件(Windows)吗?