Próbuję korzystać z natywnej biblioteki Fortran, która nie jest wątkowo bezpieczna, jednocześnie używając JNA. Ponieważ biblioteka nie jest bezpieczna dla wątków, próbuję utworzyć różne kopie tej samej biblioteki, ale najwyraźniej wydają się one współużytkować adresy pamięci. Jeśli zmodyfikuję jedną zmienną w jednej bibliotece, zmienna w drugiej bibliotece zostanie zmieniona na. Takie zachowanie uniemożliwia uruchamianie ich jednocześnie w osobnych wątkach.Problemy z pamięcią podczas ładowania dwóch rodzimych bibliotek zawierających te same symbole.
Poniższy przykład pokazuje kod co mam na myśli:
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
Plik ten jest kompilowany i kopiowane w sposób następujący:
gfortran -shared -O2 code.f -o mylib.so -fPIC
cp mylib.so mylib_copy.so
Potem dostęp przy użyciu tych dwóch 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());
}
Dane wyjściowe powyższego kodu to 9
, co oznacza, że dwie biblioteki wydają się udostępniać swoją pamięć.
Czy istnieje sposób, aby były całkowicie niezależne? Próbowałem tego samego przy użyciu kompilatora Intel Fortran, ten sam wynik.
Jak mogę się dowiedzieć, rtld_local? Używam CentOS 7 –
Otrzymuję oczekiwane zachowanie z ustawieniem 'RTLD_LOCAL = 1', chociaż myślę, że' RTLD_LOCAL' ma wartość 0 (GLIBC2.4). Jeśli ustawię 'RTLD_LOCAL = 0', to' Native.loadLibrary' narzeka, że nie można znaleźć biblioteki (tj. Tak-pliku). PS: Nie ma takiej metody 'Native.loadLibrary' z podpisem jak w twojej odpowiedzi, brakuje ci klasy interfejsu. –
Być może będziesz musiał dołączyć 'RTLD_LAZY' (który ma wartość" 1 "na OSX, nie może sprawdzić linuksowego ATM). Nie definiuj 'RTLD_LOCAL' jako" 1 ", to jest niepoprawne. Nic złego w tym, że po prostu definiujesz 'OPCJE = 1' i pozostawiasz to; nie ma potrzeby definiowania stałych, jeśli nikt inny nie użyje ponownie tej części kodu. – technomage