【问题标题】:Why does gcc link without the lpthread flag?为什么 gcc 链接没有 lpthread 标志?
【发布时间】:2018-05-21 05:15:36
【问题描述】:

我正在从事一个爱好项目,其中互斥锁的行为很神秘。我把它归结为这个显然应该死锁的测试用例。

#include <pthread.h>
#include <stdio.h>

int main() {
    pthread_mutex_t test;
    pthread_mutex_init(&test, NULL);
    pthread_mutex_lock(&test);
    pthread_mutex_lock(&test);
    printf("Took lock twice\n");
    return 0;
}

但是,当我在没有-lpthread 标志的情况下进行编译时,程序不仅仍然可以编译和链接,而且还可以在没有死锁的情况下运行。为什么?

gcc pthread_break.c -o pthread_test  
./pthread_test
Took lock twice

使用-lpthread 标志编译会产生预期的结果:

gcc pthread_break.c -o pthread_test -lpthread  
./pthread_test
     <- deadlocked here

我正在运行 GCC 版本 7.2.0。

【问题讨论】:

标签: c multithreading gcc pthreads


【解决方案1】:

这个问题似乎缺乏信息 - 但似乎有两种选择:

首先,使用PTHREAD_MUTEX_RECURSIVE 启动互斥锁,这将允许对互斥锁进行双重锁定 - 管理引用计数并且仅当引用计数为 0 时才释放互斥锁。这意味着一个人可以多次锁定同一个互斥锁次在同一个线程中,但为了释放它,必须提供相同数量的解锁。

第二,这个版本的 gcc 只实现了 pthread 函数的存根 - 这意味着如果你不添加 -lpthread 库链接指令,锁定函数不会实现。这得到了添加选项后出现死锁这一事实的支持。

我将尝试查看 GCC 源代码以验证这确实是第二个选项的结果 - 将添加更新。

注意:始终建议专门链接库,因为它允许控制结果 - GCC 内部支持的后备可能会导致意外行为,如上所示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-12
    • 2022-01-21
    • 2014-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-01
    • 2011-02-23
    相关资源
    最近更新 更多