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

发布于 2024-12-12 20:44:51 字数 619 浏览 0 评论 0原文

我在本机方法中有一个线程阻塞,该线程又阻塞并等待 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

攒一口袋星星 2024-12-19 20:44:53

不确定这是否适合您,但在类似的情况下(使用套接字读取)我诉诸关闭套接字作为“中断”。然后 read() 调用可能会返回。就我而言,它通过抛出一些异常“返回”,我捕获并处理了一个中断。即

public int myRead(g_fd, dest, len) {
   try {
      return read(g_fd, dest, len);
   }
   catch (SomeIOExceptionIForgetWhatItWas ex) {
      throw new InterruptedException();
   }
}

您可能还必须检查 -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.

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.

°如果伤别离去 2024-12-19 20:44:52

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

如果本机代码是不可避免的,那么你可以这样做。
- 以非阻塞模式打开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 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.

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;
             }
          }
       }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文