除非链接到pthread,否则没有死锁? [英] No deadlock unless linked to pthreads?

查看:91
本文介绍了除非链接到pthread,否则没有死锁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Why is it that creating a std::mutex deadlock will not actually cause a deadlock unless the program is linked to pthreads?

以下内容在与pthreads库链接时将死锁,而在未链接pthreads时将不会死锁.在gcc和clang上进行了测试.

The following will deadlock when linked with pthreads library and will not deadlock if pthreads is not linked in. Tested on gcc and clang.

// clang++ main.cpp -std=c++14 -lpthread
#include <mutex>
int main() {
    std::mutex mtx;
    mtx.lock();
    mtx.lock();
    return 0;
}

我知道没有线程库实际上不需要互斥功能,但是编译器是否知道链接的库?并可以基于此进行优化吗?

I understand that without a thread library you don't actually need mutex functionality, but is the compiler aware of the libraries that are linked in? And can it optimized based on that?

推荐答案

以下内容在与pthreads库链接时将死锁,而在未链接pthreads时将不会死锁.

The following will deadlock when linked with pthreads library and will not deadlock if pthreads is not linked in.

这是因为std::mutex::lock的默认实现没有.

编译器是否知道链接到的库?

is the compiler aware of the libraries that are linked in?

否:编译器只需调用std::mutex::lock并将其传递给mtx地址即可.行为不同的是该函数的实现.

No: the compiler simply calls std::mutex::lock and passes it the address of mtx. It's the implementation of that function that behaves differently.

更新:

为澄清起见,实现是否可以更改,取决于是否已链接库?通过宏吗?

To clarify, the implementation is able to change itself depending on if a library has been linked in? Through a macro?

在编译器完成编译时,宏预处理也已完成,并且不会产生任何进一步的影响.

By the time the compiler is done compiling, macro preprocessing is also done and can not have any further effect.

也许最好证明一下.假设您有:

Perhaps it's best to demonstrate. Suppose you have:

int main() { return foo(); }

可以告诉您上述程序的执行结果是什么吗?不,您不能,因为您不知道foo的作用.

Can you tell what the result of execution of above program is? No, you can't, because you don't know what foo does.

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

Suppose now that I compile the following:

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

gcc -c foo.c && ar ruv libfoo.a foo.o
gcc main.o -L. -lfoo

现在您可以说程序将以0返回码退出.

Now you can tell that the program will exit with 0 return code.

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

Now suppose that I also compile the following:

// bar.c
int foo() { abort(); }

gcc -c bar.c && ar ruv libbar.a bar.o

最后,我像这样链接相同的未修改 main.o:

Finally, I link the same unmodified main.o like so:

gcc main.o -L. -lbar -lfoo

您能说出生成的程序将做什么吗?

Can you tell what the resulting program will do?

您可以:它将在SIGABRT之前死亡并产生核心转储.

You can: it will die with SIGABRT and produce a core dump.

请注意,main.o并未更改,只有链接了main.o的库已更改.

Notice that main.o did not change, only the libraries that main.o is being linked against have changed.

这与导致原始程序根据是否链接到libpthread的行为完全相同的机制相同.

This is exactly the same mechanism that causes your original program to behave differently depending on whether or not it is linked against libpthread.

这篇关于除非链接到pthread,否则没有死锁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆