JNAを使用して、スレッドセーフでないネイティブのFortranライブラリを同時に操作しようとしています。ライブラリはスレッドセーフではないので、私は同じライブラリの異なるコピーをインスタンス化しようとしますが、明らかにメモリアドレスを共有しているようです。 1つのライブラリ内の1つの変数を変更すると、他のライブラリの変数は次のように変更されます。この動作により、別々のスレッドでconcurentlyで実行することができなくなります。同じシンボルを含む2つのネイティブライブラリをロードする際にメモリの問題が発生する
次のコード例は、私が何を意味するかを示しています。
code.f:
subroutine set(var)
implicit none
integer var,n
common/conc/n
n=var
end subroutine
subroutine get(var)
implicit none
integer var,n
common/conc/n
var=n
end subroutine
このファイルがコンパイルされ、次のようにコピーされます。
gfortran -shared -O2 code.f -o mylib.so -fPIC
cp mylib.so mylib_copy.so
それから私は使用して、これら2にアクセスJNA:
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;
public class JNA {
public interface MyLib extends Library {
public void set_(IntByReference var);
public void get_(IntByReference var);
}
public static void main(String[] args) {
System.setProperty("jna.library.path", ".");
MyLib lib = (MyLib) Native.loadLibrary("mylib.so", MyLib.class);
MyLib lib_copy = (MyLib) Native.loadLibrary("mylib_copy.so", MyLib.class);
# set a common variable in mylib
lib.set_(new IntByReference(9));
# access the variable in mylib_copy
IntByReference result = new IntByReference();
lib_copy.get_(result);
System.out.println(result.getValue());
}
上記のコードの出力は9
です。つまり、2つのライブラリがメモリを共有しているようです。
完全に独立させる方法はありますか?私は同じ結果をインテルFortranコンパイラを使って同じものを試しました。
rtld_localをどのように見つけることができますか?私はCentOS 7を使用しています –
'RTLD_LOCAL'は値0(GLIBC2.4)を持っているとは思いますが、予想される動作は' RTLD_LOCAL = 1'で設定します。 'RTLD_LOCAL = 0'を設定した場合、' Native.loadLibrary'はライブラリ(つまりsoファイル)が見つからないと告げる。 PS:あなたの答えのような署名を持つメソッドNative.loadLibraryはありません。あなたはインターフェイスクラスがありません。 –
'RTLD_LAZY'(OSXでは" 1 "の値を持ち、LinuxのATMはチェックできません)を含める必要があるかもしれません。 'RTLD_LOCAL'を" 1 "と定義しないでください。それは間違っています。 'OPTIONS = 1'を定義してそれを残しておけば何も問題ありません。誰もコードのその部分を再利用することがない場合は、定数を定義する必要はありません。 – technomage