C 多线程应用程序中的dlopen()以“退出”;跟踪/BPT陷阱“;

C 多线程应用程序中的dlopen()以“退出”;跟踪/BPT陷阱“;,c,multithreading,trace,dlopen,C,Multithreading,Trace,Dlopen,我尝试在运行时使用以下命令在用C编写的Mac OS X应用程序中加载框架: dlopen("/System/Library/Frameworks/JavaVM.framework/JavaVM",RTLD_LAZY); 如果我从主线程调用dlopen() 当我从另一个线程调用它时,应用程序退出并出现错误:Trace/BPT trap 这是从主线程调用dlopen() 输出为:加载了库JavaVM 这是从另一个线程调用dlopen()的代码(并在调用该函数时退出): 输出为:跟踪/BPT陷阱 错

我尝试在运行时使用以下命令在用C编写的Mac OS X应用程序中加载框架:

dlopen("/System/Library/Frameworks/JavaVM.framework/JavaVM",RTLD_LAZY);
如果我从主线程调用
dlopen()

当我从另一个线程调用它时,应用程序退出并出现错误:
Trace/BPT trap

这是从主线程调用
dlopen()

输出为:加载了库JavaVM

这是从另一个线程调用
dlopen()
的代码(并在调用该函数时退出):

输出为:跟踪/BPT陷阱

错在哪里? 抱歉,如果这是一个愚蠢的问题,但我还是一个新手

看来dlopen()不是线程安全的,所以你不应该在多线程下调用它。
或者,可能不是dlopen()不是线程安全的,而是库的初始化代码在加载时运行

没有理由在threads下调用dlopen,因为它不会多次加载库。
当您多次加载同一个文件时,第二次不执行任何操作(除了增加一些refcount),只返回相同的句柄。因此,通过每个线程加载它,您将一无所获。

可以使用dlmopen()多次真正加载库。但限制为15次。

即使这样,在启动线程之前,也应该在main()中执行此操作(并为每个线程提供其库句柄),而不是从线程内部执行。

以注释而不是答案的形式发布,因为我不是100%确定这一点,但我非常确定JVM希望在主线程上初始化,否则将无法工作。一旦启动,它就会创建许多自己的线程,并对其环境做出许多假设,其中可能包括在原始线程上启动。如果有人能提供一个有效的反例,我很高兴收回我的主张。@ErnestFriedman Hill谢谢你的回答。Apple技术说明中写道:将JVM嵌入本机Mac OS X应用程序与其他平台有一个主要区别:如果使用AWT,JVM不得在应用程序的主线程上启动。许多教程和文档在主线程上启动JVM,因此认识到Mac OS X的这一独特需求非常重要。因为我需要使用AWT,所以我需要在另一个线程上启动JVM。谢谢!我在主线程中使用了dlopen(),然后将句柄传递给新创建的线程。它现在可以正常工作。顺便说一句,如果您尝试在多线程上下文中使用
lt_dlopen
libtool包装调用,也会发生这种行为。
int main(int argc, char** argv)
{

    void *result = dlopen("/System/Library/Frameworks/JavaVM.framework/JavaVM",RTLD_LAZY);
    if (!result) {
        printf("can't open library JavaVM: %s\n", dlerror());
    }
    else {
        printf("library JavaVM loaded\n");
    }

    return 0;
}
void *loadJava(void* arg)
{
    void *result = dlopen("/System/Library/Frameworks/JavaVM.framework/JavaVM",RTLD_LAZY);
    if (!result) {
        printf("can't open library JavaVM: %s\n", dlerror());
    }
    else {
        printf("library JavaVM loaded\n");
    }
}

int main(int argc, char** argv)
{
    pthread_t vmthread;

    struct rlimit limit;
    size_t stack_size = 0;
    int rc = getrlimit(RLIMIT_STACK, &limit);
    if (rc == 0) {
        if (limit.rlim_cur != 0LL) {
            stack_size = (size_t)limit.rlim_cur;
        }
    }

    pthread_attr_t thread_attr;
    pthread_attr_init(&thread_attr);
    pthread_attr_setscope(&thread_attr, PTHREAD_SCOPE_SYSTEM);
    pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
    if (stack_size > 0) {
        pthread_attr_setstacksize(&thread_attr, stack_size);
    }

    pthread_create(&vmthread, &thread_attr, loadJava, NULL);
    pthread_attr_destroy(&thread_attr);

    pthread_exit(NULL);

    return 0;
}