暂停通过JNI运行的本机C代码

时间:2013-08-01 18:17:25

标签: java c java-native-interface signals

我正在运行一个Java应用程序,后者又会调用一些C代码。在Java中,我创建了一个线程,其唯一的职责是执行对C代码的调用。

我如何暂停执行C代码?到目前为止,我已经花了一天的时间来研究它,我不确定我是否应该尝试在Java或C级暂停。

下面我有调用public native String beginTest()的线程的java代码。

public void run() {
    int result = this.beginTest();
    AmpTester.setResponseValue(result);
}

为简单起见,我们假设JNI接口和本机方法定义如下:

JNIEXPORT jstring JNICALL Java_AmpTester_beginTest (JNIEnv *env, jobject obj){
    return startAmpTest();
}

我想要运行的实际本机代码:

int startTest(){
    int i;
    for (i = 0; i < 1000; i++){
        printf("%i\n", i);
        sleep(1);
    }

    return 0;
}

1 个答案:

答案 0 :(得分:0)

Java的Thread.suspend() 可能是(取决于JVM,但我怀疑任何人都会这样实现它)不起作用,但我也不推荐它。您可以使用操作系统的SuspendThread功能,但我也不建议这样做。暂停线程很糟糕:

  

Thread.suspend本身就容易出现死锁。如果目标线程在监视器上保持锁定,在挂起时保护关键系统资源,则在恢复目标线程之前,任何线程都无法访问此资源。如果恢复目标线程的线程在调用resume之前尝试锁定此监视器,则会导致死锁。这种死锁通常表现为“冻结”过程。

来源:Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?

根据文档,windows SuspendThread函数主要是为调试器使用而设计的(出于类似的原因)。所以基本上答案是你不应该暂停执行任何代码,包括你的C代码。


但您可以使用独占锁/互斥锁和全局变量来解决您的问题:在循环的每次迭代中,检查全局volatile bool变量是否仍为true。如果不是,请获取锁定,将其设置回true,释放锁定,然后继续迭代。

您的suspend()函数将如下所示:获取锁定并将变量设置为false

您的resume()功能如下所示:解除锁定。

您可以通过JNI调用这些功能。

示例:本机方法正在迭代(线程A)。现在线程B调用suspend()。它获取锁并更改变量。现在,线程A注意到,并且在获取锁定的过程中,等待线程B释放它。最后,线程B调用resume()并释放锁。现在,线程A获取它,更改值,释放它并继续迭代。

相关问题