为什么 pthread_cond_wait() 在未与“-lpthread”链接时不阻塞?
Why does pthread_cond_wait() not block when not linked with "-lpthread"?
我正在学习 pthread_cond_t
并编写了以下代码,旨在永远阻止 pthread_cond_wait()
:
// main.cpp
// Intentionally blocks forever.
#include <iostream>
#include <cstring>
#include <cerrno>
#include <pthread.h>
int main( int argc, char* argv[] )
{
pthread_cond_t cond;
if ( pthread_cond_init( &cond, NULL ) )
{
std::cout << "pthread_cond_init() failed: " << errno << "(" << strerror( errno ) << ")" << std::endl;
}
pthread_mutex_t mutex;
if ( pthread_mutex_init( &mutex, NULL ) )
{
std::cout << "pthread_mutex_init() failed: " << errno << "(" << strerror( errno ) << ")" << std::endl;
}
pthread_mutex_lock( &mutex );
pthread_cond_wait( &cond, &mutex );
pthread_cond_destroy( &cond );
return 0;
}
当我第一次 compiled/executed 这个程序时,可执行文件 没有 挂起 - 它退出了:
>g++ --version
g++ (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
>g++ -g main.cpp && ./a.out
> // <-- Note: returned to bash prompt
接下来我尝试 linking 反对 libpthread
- 现在 可执行文件如预期的那样挂起:
>g++ -g main.cpp -lpthread && ./a.out
^C
> // <-- Needed to send SIGINT to terminate process
我实际上期望为所需的 pthread
函数打一个 link 错误;为什么我没有明确地 link 反对 libpthread
而没有遇到一个?
上述问题的答案可能会使这个问题变得毫无意义,但是在没有显式 link libpthread
的情况下进行编译时,为什么生成的二进制文件 "skip over" 或忽略 pthead_cond_wait()
? glibc 或其他地方是否有一些默认的 pthread 函数实现?
当您的进程是多线程时,一些 glibc 函数需要锁定。
为了避免每次都拖入 libpthread 依赖项,glibc 使用 weakrefs 来引用一堆 pthread 功能。如果它检测到功能不可用(由于 weakref 解决方案,这不会导致链接器错误),它将把这些操作默认为无操作(这很好,因为如果你没有 pthreads,你就不能是多线程的,不需要锁定)。
此解决方案的结果是您获得的行为。
我正在学习 pthread_cond_t
并编写了以下代码,旨在永远阻止 pthread_cond_wait()
:
// main.cpp
// Intentionally blocks forever.
#include <iostream>
#include <cstring>
#include <cerrno>
#include <pthread.h>
int main( int argc, char* argv[] )
{
pthread_cond_t cond;
if ( pthread_cond_init( &cond, NULL ) )
{
std::cout << "pthread_cond_init() failed: " << errno << "(" << strerror( errno ) << ")" << std::endl;
}
pthread_mutex_t mutex;
if ( pthread_mutex_init( &mutex, NULL ) )
{
std::cout << "pthread_mutex_init() failed: " << errno << "(" << strerror( errno ) << ")" << std::endl;
}
pthread_mutex_lock( &mutex );
pthread_cond_wait( &cond, &mutex );
pthread_cond_destroy( &cond );
return 0;
}
当我第一次 compiled/executed 这个程序时,可执行文件 没有 挂起 - 它退出了:
>g++ --version
g++ (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
>g++ -g main.cpp && ./a.out
> // <-- Note: returned to bash prompt
接下来我尝试 linking 反对 libpthread
- 现在 可执行文件如预期的那样挂起:
>g++ -g main.cpp -lpthread && ./a.out
^C
> // <-- Needed to send SIGINT to terminate process
我实际上期望为所需的 pthread
函数打一个 link 错误;为什么我没有明确地 link 反对 libpthread
而没有遇到一个?
上述问题的答案可能会使这个问题变得毫无意义,但是在没有显式 link libpthread
的情况下进行编译时,为什么生成的二进制文件 "skip over" 或忽略 pthead_cond_wait()
? glibc 或其他地方是否有一些默认的 pthread 函数实现?
当您的进程是多线程时,一些 glibc 函数需要锁定。 为了避免每次都拖入 libpthread 依赖项,glibc 使用 weakrefs 来引用一堆 pthread 功能。如果它检测到功能不可用(由于 weakref 解决方案,这不会导致链接器错误),它将把这些操作默认为无操作(这很好,因为如果你没有 pthreads,你就不能是多线程的,不需要锁定)。 此解决方案的结果是您获得的行为。