不与“ -lpthread”链接时,为什么pthread_cond_wait()不会阻塞?

时间:2018-07-03 20:57:57

标签: c++ c pthreads glibc condition-variable

我正在学习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;
}

当我第一次编译/执行该程序时,可执行文件没有挂起-它退出了:

>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

接下来,我尝试针对libpthread进行链接-并且现在可执行文件已按预期方式挂起:

>g++ -g main.cpp -lpthread && ./a.out 
^C
> // <-- Needed to send SIGINT to terminate process

我实际上期望遇到必需的pthread函数的链接错误;当我未明确链接到libpthread时为什么没有遇到一个?

上面的回答可能使这个问题没有意义,但是当编译时没有显式链接libpthread时,为什么生成的二进制“跳过”或忽略pthead_cond_wait()?在glibc或其他地方是否有一些默认的不执行pthread函数的实现?

1 个答案:

答案 0 :(得分:7)

当您的进程为多线程时,某些glibc函数需要锁定。 为了避免每次都拖入libpthread依赖项,glibc使用weakrefs来引用一堆pthread功能。如果它检测到该功能不可用(不会因为weakref解决方案而导致链接器错误),它将默认将这些操作设置为无操作(这很好,因为如果您没有pthread,则无法是多线程的,则不需要锁定)。 该解决方案的结果就是您得到的行为。