A warning would have been helpful for this case of missed -pthread. Normally a runtime error is at least generated but the following C++11 code compiles fine with all warnings enabled, and also executes without run time errors, but does so incorrectly if -pthread is not given. (wait_for is then just skipped). cheers Johan. #include <chrono> #include <mutex> #include <condition_variable> void sleep10(){ // sleeps only of -pthread is used std::mutex m; std::condition_variable cv; std::unique_lock<std::mutex> lk(m); cv.wait_for(lk,std::chrono::seconds{10}); }
I'm not really sure what we can do here. You need to use -pthread.
I suppose we could turn all timed waiting functions into sleeps, and wait() into an infinite loop, when libpthread is not linked in, but I'd prefer not to add that complexity.
(In reply to Jonathan Wakely from comment #2) > I suppose we could turn all timed waiting functions into sleeps, and wait() > into an infinite loop, when libpthread is not linked in, but I'd prefer not > to add that complexity. I agree, that sounds too much. The documentation of -pthread states that it sets flags for the preprocessor in addition to the linker and at least on my system, _REENTRANT is set by -pthreads. If that's a canonical way to detect threading support I suggest checking it in the headers that rely on threading: #ifndef _REENTRANT #error "No thread support enabled." #endif If there are reasons this is not a good idea so be it.
I don't think -pthread sets _REENTRANT for all targets, although it might do for all those where we actually support std::condition_variable.
Also, some people compile without -pthread then link with -lpthread manually. We could say that's technically unsupported, but currently it works.
I'd say most people compile with -lpthread, I think glibc only keyes a single prototype on _REENTRANT (getlogin_r) and even that is also enabled by POSIX 1995 feature test macro too (which is on by default). So, conditionalizing something on _REENTRANT sounds a wrong idea to me.
related to PR 55394
This has just caused me major headache because the behavior is completely unexpected. The root problem to me seems to be that pthread_cond_wait is defined not just in libphread, but also in libc: # objdump -TC /lib/libc.so.6 | grep cond_wait 0014a570 g DF .text 00000033 (GLIBC_2.0) pthread_cond_wait 0007f5c0 g DF .text 00000033 GLIBC_2.3.2 pthread_cond_wait Why is that even in there? And if I apparently end up calling this implementation, why doesn't block the way it should?
The GNU libc has no-op stubs for several pthread functions. I think that is done so that single threaded programs which don't actually need those functions can still link to libraries that have references to those functions. They don't block because they're not for use in multithreaded programs. If you need the real versions you need to link to libpthread.
(In reply to Jonathan Wakely from comment #9) > The GNU libc has no-op stubs for several pthread functions. I think that is > done so that single threaded programs which don't actually need those > functions can still link to libraries that have references to those > functions. > > They don't block because they're not for use in multithreaded programs. If > you need the real versions you need to link to libpthread. OK, thanks for the clarification. But I feel I need to point out that that's just a huge WTF. How is a C++ dev supposed to know from the standard docs they work with all day that a condition_variable has any relation to libpthread? Least of all if you're used to getting linker errors if you're missing an implementation. I've read up on it a little bit and I can understand the rationale for having no-op mutex-related stuff because that doesn't break behavior in single-threaded code. But wait conditions are supposed to (mostly) block, single-threaded or not. A no-op stub is a severe breach of protocol there because no one expects to get "spurious" wakeups at 100% CPU. Just think about something like this happening in a real-time system. Maybe this should rather be a glibc bug. Any opinions on that?
(In reply to Victor Mataré from comment #10) > OK, thanks for the clarification. But I feel I need to point out that that's > just a huge WTF. How is a C++ dev supposed to know from the standard docs > they work with all day that a condition_variable has any relation to > libpthread? You're not compiling with the standard, you're using GCC. The requirement to use libpthread is documented by the implementation (although it could be easier to find): https://gcc.gnu.org/onlinedocs/libstdc++/manual/using.html#manual.intro.using.flags