C++ 没有死锁,除非链接到pthreads?

C++ 没有死锁,除非链接到pthreads?,c++,linker,pthreads,mutex,compiler-optimization,C++,Linker,Pthreads,Mutex,Compiler Optimization,为什么创建std::mutex死锁实际上不会导致死锁,除非程序链接到pthreads 以下内容在与pthreads库链接时将死锁,如果未在中链接pthreads,则不会死锁。在gcc和clang上测试 // clang++ main.cpp -std=c++14 -lpthread #include <mutex> int main() { std::mutex mtx; mtx.lock(); mtx.lock(); return 0; } //c

为什么创建std::mutex死锁实际上不会导致死锁,除非程序链接到pthreads

以下内容在与pthreads库链接时将死锁,如果未在中链接pthreads,则不会死锁。在gcc和clang上测试

// clang++ main.cpp -std=c++14 -lpthread
#include <mutex>
int main() {
    std::mutex mtx;
    mtx.lock();
    mtx.lock();
    return 0;
}
//clang++main.cpp-std=c++14-lpthread
#包括
int main(){
std::互斥mtx;
mtx.lock();
mtx.lock();
返回0;
}
我知道,如果没有线程库,您实际上不需要互斥函数,但是编译器知道链接到其中的库吗?它能在此基础上进行优化吗

以下内容在与pthreads库链接时将死锁,如果未在中链接pthreads,则不会死锁

这是因为
std::mutex::lock
的默认实现不起任何作用

编译器是否知道中链接的库

否:编译器只需调用
std::mutex::lock
并将
mtx
的地址传递给它。正是该函数的实现表现出不同的行为

更新:


为了澄清这一点,实现能够根据库是否已链接到而改变自身?通过宏

当编译器完成编译时,宏预处理也完成了,不能产生任何进一步的效果

也许最好是演示一下。假设你有:

int main() { return foo(); }
你能告诉我执行上述程序的结果吗?不,你不能,因为你不知道
foo
做什么

现在假设我编译了以下内容:

// foo.c
int foo() { return 0; }

gcc -c foo.c && ar ruv libfoo.a foo.o
gcc main.o -L. -lfoo
// bar.c
int foo() { abort(); }

gcc -c bar.c && ar ruv libbar.a bar.o
现在您可以知道程序将以
0
返回代码退出

现在假设我还编译了以下内容:

// foo.c
int foo() { return 0; }

gcc -c foo.c && ar ruv libfoo.a foo.o
gcc main.o -L. -lfoo
// bar.c
int foo() { abort(); }

gcc -c bar.c && ar ruv libbar.a bar.o
最后,我链接相同的未修改的
main.o
,如下所示:

gcc main.o -L. -lbar -lfoo
你能告诉我结果是什么吗

您可以:它将随着
SIGABRT
死亡并产生一个内核转储

请注意,
main.o
没有更改,只有链接到的
main.o
库发生了更改


这与导致原始程序行为不同的机制完全相同,这取决于它是否链接到
libpthread

fyi“如果锁是由已经拥有互斥锁的线程调用的,则行为未定义:…”来源:为了澄清,根据库是否已链接到,实现是否能够自行更改?通过宏?为什么允许同一符号的多个定义?@a-n-t-h-o-n-y中没有多个定义链接。要理解为什么会这样,你可以阅读