为什么没有lpthread标志的gcc链接?

时间:2017-12-07 06:56:01

标签: c multithreading gcc pthreads

我正在做一个互动项目,其中互斥体表现得很神秘。我把它归结为这个应该明显陷入僵局的测试用例。

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

1 个答案:

答案 0 :(得分:1)

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

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

第二个是,此版本中的gcc仅为pthread函数实现存根 - 这意味着如果不添加-lpthread库链接指令,则不会实现锁定函数。这一点得到以下事实的支持:添加选项后,会出现死锁。

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

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