为什么只能在Java的“主”线程上调用使用OpenMP编译的JNI库?

时间:2010-01-03 22:38:52

标签: java-native-interface openmp

我用C语言编写了一个库,使用各种#pragma omp指令来并行执行。我在Mac OS X 10.6上。然后我将这些函数包装在JNI库中,并从我的Java应用程序中调用它们。

如果从主线程之外的Java线程调用它们,那么对包含OpenMP指令的本机函数的调用似乎会因EXC_BAD_ACCCESS而崩溃 - 换句话说,

public static void main(String[] args) { nativeCall(); }

工作,但在另一个线程上调用库,比如说EventQueue

    public static void main(String[] args) { 
         SwingUtilities.invokeLater(
             new Runnable(){
                public void run() { nativeCall(); }
});}

与EXC_BAD_ACCESS崩溃。

我是OpenMP的新手,所以我不确定是什么导致这种情况。 java“main”线程有什么特别之处?它是否以某种特权模式运行,只有它才能访问初始化OpenMP并行化任务所需的资源?我也不熟悉OS X上JVM的内部工作原理,所以我不确定Java线程和本机线程之间的关系是什么。

感谢任何帮助!

4 个答案:

答案 0 :(得分:1)

您没有显示您通过JNI调用的本机代码并且使用OpenMP,因此这只是一个猜测:如果您使用JNIEnv *(您作为本机方法的参数获得)访问任何jvm资源并行化代码,你要求麻烦。 JNIEnv *只能在获得它的线程中使用。请参阅http://java.sun.com/docs/books/jni/html/pitfalls.html#11233

还有一个链接指向如何获取当前线程的JNIEnv *。我不知道可能有多快或多慢,所以如果你的并行化计算很小,它可能会通过并行化来获得你所获得的好处。

答案 1 :(得分:0)

我非常怀疑我可以根据我编写OpenMP的有限经验来解释您的问题。由于没有其他人办理登机手续,

OpenMP希望管理流程中的线程。这是它的工作原理;它使线程。它希望从主线程启动并从那里开始。

我会假设即使没有JNI,从非主线程启动OpenMP也会令人担忧。你可以发布问题的回溯,这也可能提供线索吗?

请记住,JVM的其余部分未使用启用OpenMP的编译器选项进行编译。

答案 2 :(得分:0)

Java正式支持OpenMP不受支持。一些机构正在探索线程执行模型,其中一个探索是JOMP(Java for OpenMP)

答案 3 :(得分:0)

使用gcc 4.7.3或更高版本。

当我使用gcc 4.2.1(与Xcode一起安装)时,我看到了同样的错误。 但是使用gcc 4.7.3,没有发生错误。