Почему pthread_cond_wait () не блокируется, когда не связан с "-lpthread"? - PullRequest
0 голосов
/ 03 июля 2018

Я изучаю 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 в glibc или где-то еще?

1 Ответ

0 голосов
/ 04 июля 2018

Некоторые функции glibc требуют блокировки, когда ваш процесс многопоточный. Чтобы избежать перетаскивания зависимости libpthread каждый раз из-за этого, glibc использует слабые ссылки для ссылки на множество функций pthread. Если он обнаружит, что функциональность недоступна (что не приведет к ошибке компоновщика из-за слабого решения), то по умолчанию эти операции будут заменены на no-ops (что вполне нормально, потому что если у вас нет pthreads, вы не сможете быть многопоточным и блокировка не требуется). Результатом этого решения является поведение, которое вы получаете.

...