为什么pthread_cond_wait()在没有与"-lpthread"链接时不会阻塞?

Sto*_*row 3 c c++ glibc pthreads 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;
}
Run Code Online (Sandbox Code Playgroud)

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

>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
Run Code Online (Sandbox Code Playgroud)

接下来我尝试链接libpthread- 现在可执行文件挂起,如预期的那样:

>g++ -g main.cpp -lpthread && ./a.out 
^C
> // <-- Needed to send SIGINT to terminate process
Run Code Online (Sandbox Code Playgroud)

我实际上期望为所需的pthread功能发出链接错误; 当我没有明确链接时,为什么我没有遇到过libpthread

这个问题可能由于上面的答案而变得没有问题,但是当没有显式链接进行编译时libpthread,为什么生成的二进制"跳过"或忽略pthead_cond_wait()?glibc或某处的pthread函数是否有一些默认的do-nothing实现?

PSk*_*cik 8

当您的进程是多线程时,某些glibc函数需要锁定.为了避免每次因为libpthread依赖性而拖拽,glibc使用weakrefs来引用一堆pthread功能.如果它检测到功能不可用(由于weakref解决方案不会导致链接器错误),它会将那些操作默认为no-ops(这很好,因为如果你没有pthreads,你就不能多线程并且不需要锁定).这个解决方案的结果就是你得到的行为.