加载包含相同符号的两个本机库时出现内存问题 [英] Memory issues while loading two native libraries containing same symbols

查看:211
本文介绍了加载包含相同符号的两个本机库时出现内存问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用JNA同时运行本地,非线程安全的Fortran库。由于库不是线程安全的,我尝试实例化同一个库的不同副本,但显然它们似乎共享内存地址。如果我在一个库中修改一个变量,则其他库中的变量将被修改为。这种行为使得不可能在单独的线程中一致地运行它们。



以下代码示例演示了我的意思:

code.f:

 子程序集(var)
隐含无
整数变量,n
共同/浓度/ n
n = var
结束子程序

子程序get(var)
隐含无
整数变量,n
共同/浓缩/ n
var = n
结束子程序

这个文件被编译和复制如下:

  gfortran -shared -O2 code.f -o mylib.so -fPIC 
cp mylib.so mylib_copy.so
code>

然后我使用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);

#在mylib中设置一个公共变量
lib.set_(new IntByReference(9));

#访问mylib_copy中的变量
IntByReference result = new IntByReference();
lib_copy.get_(result);
System.out.println(result.getValue());




$ b $ p
$ b

以上代码的输出是 9 ,这意味着两个库似乎分享他们的记忆。



有没有办法让它们完全独立?我试过使用英特尔Fortran编译器,结果相同。

解决方案

当通过<$ c打开库时,JNA使用RTLD_LAZY | RTLD_GLOBAL $ c> dlopen ,这可能是为什么符号被共享。你可以像这样覆盖这些标志:

  int RTLD_LOCAL = ??; //在你的系统上查看
Map options = new HashMap();
options.put(Library.OPTION_OPEN_FLAGS,RTLD_LOCAL);
MyLib mylib = Native.loadLibrary(mylib,MyLib.class,options);
MyLib mylib2 = Native.loadLibrary(mylib2,MyLib.class,options);


I'm trying to operate a native, non-thread-safe Fortran library concurrently using JNA. As the library is not thread-safe, I try to instantiate different copies of the same library, but apparently they seem to share memory addresses. If I modify one variable in one library, the variable in the other library is modified to. This behavior makes it impossible to run them concurently in separate threads.

The following code example demonstrates what I mean:

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

This file is compiled and copied as follows:

gfortran -shared -O2 code.f -o mylib.so -fPIC
cp mylib.so mylib_copy.so

Then I access those two using 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());

    }

The output of the above code is 9, whichs means the two libraries seem to share their memory.

Is there a way to make them completely independent? I tried the same using Intel Fortran compiler, same result.

解决方案

JNA uses RTLD_LAZY|RTLD_GLOBAL when opening a library via dlopen, which is probably why the symbols are being shared. You can override those flags like so:

int RTLD_LOCAL = ??; // look this up on your system
Map options = new HashMap();
options.put(Library.OPTION_OPEN_FLAGS, RTLD_LOCAL);
MyLib mylib = Native.loadLibrary("mylib", MyLib.class, options);
MyLib mylib2 = Native.loadLibrary("mylib2", MyLib.class, options);

这篇关于加载包含相同符号的两个本机库时出现内存问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆