为什么gcc在链接时不需要-lpthread标志?

6

我正在做一个业余项目,其中互斥锁的行为很神秘。我将其简化为这个测试案例,应该会明显地死锁。

#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。


相关答案,但不是重复的问题。 - R.. GitHub STOP HELPING ICE
1
你使用哪个平台?也许标准库包含Pthread函数,或者是始终报告“未实现”错误的虚拟版本。你是否勤奋地检查每个退出代码并仔细报告错误? - Jonathan Leffler
另外,也许你应该查一下递归互斥锁。 - Jonathan Leffler
1个回答

2
这个问题似乎缺乏信息,但看起来有两个选项:
首先,互斥锁使用了PTHREAD_MUTEX_RECURSIVE进行初始化,这将允许对互斥锁进行多次加锁 - 引用计数被管理,并且只有在引用计数为0时才会释放互斥锁。这意味着可以在同一线程中多次锁定同一互斥锁,但为了释放它,必须提供相同数量的解锁。
其次,是在此版本中gcc仅实现了pthread函数的存根 - 这意味着如果您不添加-lpthread库链接指令,则锁定函数不会被实现。这得到了支持,因为在添加该选项后,死锁出现了。
我将尝试查看GCC源代码以验证这确实是第二个选项的结果 - 将添加更新。
注意:始终建议专门链接库,因为这样可以控制结果 - 回退到GCC内部支持可能会导致意外行为,如上所示。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接