I'm learning about pthread_cond_t
and wrote the following code intended to block forever at the 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;
}
When I first compiled/executed this program, the executable did not hang - it exited:
>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
Next I tried linking against libpthread
- and now the executable hung, as expected:
>g++ -g main.cpp -lpthread && ./a.out
^C
> // <-- Needed to send SIGINT to terminate process
I was actually expecting to hit a link error for the required pthread
functions; why did I not encounter one when I did not explicitly link against libpthread
?
This question may be rendered moot by the answer to the above, but when compiling without the explicit link the libpthread
, why did the resulting binary "skip over" or ignore the pthead_cond_wait()
? Is there some default do-nothing implementation for pthread functions in glibc or somewhere?
Some glibc functions need locking when your process is multithreaded. To avoid dragging in the libpthread dependency everytime because of that, glibc uses weakrefs to refer to a bunch of pthread functionality. If it detects the functionality is not available (which won't cause a linker error because of the weakref solution) it will default those ops to no-ops (which is just fine because if you don't have pthreads, you can't be multithreaded and locking isn't needed). The upshot of this solution is the behavior you're getting.