【问题标题】:Ending a Java thread in C (JNI)在 C (JNI) 中结束 Java 线程
【发布时间】:2011-05-22 21:08:23
【问题描述】:

尊敬的多线程/Java/C/JNI 大师,

我有一个稍微具体的问题。我有一个生成线程的 Java 程序。在run()方法中,调用C(通过JNI),首先在TLS中分配线程局部变量,然后进入一个event_loop(所以线程的默认生命周期由这个循环决定) .

我现在的问题是如果发生类似 SIGSEGV 之类的事情,如何能够关闭/杀死线程。重要的是整个过程和其中的其他线程可以继续。这就是我们使用 TLS 分离线程的原因。

(我知道,有些人不鼓励这样做,当然做防御性编程是正确的,试图提前避免这种崩溃。这段代码仅用于迁移期间,因为我们正在从 C 更改为 Java . 但是由于我们拥有的资源很少,这需要一些时间。)

class MyThread extends Thread {
   run() {
      //wrapping the following with try-catch and throwing exception in signal 
      //handler on C side possible?
      callNativeCFunction(); //allocates TLS, enters event_loop()
   }
}

如果我使用 signal.h,我的信号处理程序会在线程上下文中调用吗?我可以访问 TLS 变量吗?然后我可以通过指向 JVM 的 env 指针以某种方式抛出异常以跳出 run() 吗? 或者我可以在 Java 线程上调用 interrupt(),例如在 Bruce Eckel 的书中提到(见下文)。

最后,还有一个问题: SIGSEGV 是 Posix 世界, STATUS_ACCESS_VIOLATION 是 Windows 世界。当我在 Windows 的 C 代码中尝试以下操作时:

 char *s = "hello world";
     *s = 'H';

我没有收到 SIGSEGV,(但我猜是 STATUS_ACCESS_VIOLATION)。由于我使用的是 signal.h,因此我只能处理非常有限的一组可用信号。你也知道我该如何处理上述情况吗?

还是在 C 端使用 pthreads 并在信号处理程序中调用 pthread_exit() 会更好(想法来自下面的第一个链接)?

那是我的问题。我将非常感谢任何帮助。非常感谢。

有用的线程;)我发现:

【问题讨论】:

    标签: java c multithreading java-native-interface kill


    【解决方案1】:

    信号处理程序所要做的就是说服函数 (callNativeCFunction()) 返回。如果C 有循环,让他们检查模块变量(signaledshutdowndone 或类似的)。

    如果在调用函数后,线程退出,则一切就绪。否则,函数可能应该返回一个状态,指示线程是否应该终止。

    【讨论】:

    • 是的,这是 Bruce Eckel 在他的书中提到的一种方式。但是由于在导致类似 SIGSEGV(我得到一个 EXCEPTION_CONTINUE_EXECUTION)之后让线程运行是很危险的,所以我搜索了一种方法来立即将其从信号处理程序中关闭(可能在 Java 对象上调用 interrupt() 方法; 当然,这在信号处理程序中也可能是危险的;但我已经成功地从信号处理程序对我的线程对象调用了一个自写的 getThreadId() 方法。
    • 此外,如何在 Windows 中捕获 STATUS_ACCESS_VIOLATION 仍然是一个开放点。你知道一种方法吗,例如通过第三个图书馆?我找到了 GNU libsigsegv (libsigsegv.sourceforge.net),但不确定它是否适合我的问题。
    • 我们目前在 Windows 端使用结构化异常处理 (SEH) 解决了这个问题,如下所述:oracle.com/technetwork/java/javase/signals-139944.html#gbzdn 所以,C 端的函数 callNativeCFunction() 以 __try 开头,以 __except 结尾,所以我们的事件循环被这两个宏包裹了。如果发生异常,程序流会跳转到 __except 子句(即跳出​​我们的事件循环)并且线程有效地结束,因为 callNativeCFunction() 结束,返回到 Java 端,其中 run() 方法(因此整个线程)结束。
    • 现在剩下的就是为 Linux 案例找到一个解决方案,我认为这将基于 signal.h。如果我知道更多,我会告诉你。
    猜你喜欢
    • 2012-12-08
    • 2019-05-09
    • 1970-01-01
    • 2013-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多