13

Java から C/C++ を呼び出す場合、Java スレッドが待機している間に C/C++ コードを実行するために、JavaVM または JNI によって新しいスレッドが作成されますか? 私の C/C++ コードは GPU で何かを実行し、結果を返すために特定のバッファをチェックする必要があるため、これを尋ねます。結果が得られたら、Java 関数を再度呼び出す必要があります。

そのため、バッファを継続的にチェックし、利用可能なデータがあればJava側にコールバックするスレッドをC++側に作成することを考えていました。

4

1 に答える 1

19

JNI は、バックグラウンドで新しいスレッドを作成しません。ネイティブ関数は、ネイティブ関数を呼び出す Java メソッドと同じスレッドで実行されます。逆に、ネイティブ コードが Java メソッドを呼び出すと、Java メソッドは、メソッドを呼び出すネイティブ コードと同じスレッドで実行されます。

これには結果があります。ネイティブ関数が戻ると、ネイティブ関数呼び出しは Java コードに戻り、呼び出された Java メソッドが戻ると、ネイティブ コードは実行を継続します。

別のスレッドで実行する必要がある処理をネイティブ コードが実行する場合、スレッドを明示的に作成する必要があります。新しい Java スレッドを作成し、この専用スレッドからネイティブ メソッドを呼び出すことができます。または、ネイティブ コードで新しいネイティブ スレッドを作成し、それを開始して、ネイティブ関数から戻ることもできます。

// Call a native function in a dedicated java thread
native void cFunction();
...
new Thread() {
    public void run() {
        cFunction();
    }
};

// Create a native thread - java part
native void cFunction()
...
cFunction();

//  Create a native thread - C part
void *processing_function(void *p);
JNIEXPORT void JNICALL Java____cFunction(JNIEnv *e, jobject obj) {
    pthread_t t;
    pthread_create(&t, NULL, processing_function, NULL);    
}

2 番目のバリアントを使用し、ネイティブに作成されたスレッドから Java コールバックを呼び出したい場合は、スレッドを JVM にアタッチする必要があります。どうやってするの?JNI アタッチ/デタッチ スレッドのメモリ管理を参照してください...

于 2016-07-17T17:14:53.473 に答える