g++ - Why do I have to pass "-pthread" option while using std::thread?
Asked Answered
G

3

16

I'm just trying to understand a concept used by g++. Here my very simple std::thread application:

#include <iostream>
#include <thread>

void func() {
    std::cout << "Running..." <<  std::endl;
}

int main()
{
    std::thread t(func);
    t.join();
    return 0;
}

I'm able to compile it on macOs/Xcode 9.0 setup with following command:

g++ main.cpp -std=c++11

But I'm unable to compile it on Linux with the same command, as far as I know I have to pass -pthread option too. Otherwise it gives me following error:

gcc version 7.1.1 20170622 (Red Hat 7.1.1-3)

main.o: In function `std::thread::thread<void (&)()>(void (&)())':
/usr/include/c++/5/thread:137: undefined reference to `pthread_create'

I think it's illogical and I shouldn't even know that it's implementing the std::thread class via pthread. Why do I have to pass -pthread option and link against pthread library? Isn't C++11 supposed to abstract me away from platform specific details? Or do I have any other alternative libraries such as pthread that I can link against for my std::thread usage? Or should I report that as a bug?

Thanks.

Gelatin answered 28/10, 2017 at 22:8 Comment(6)
Using a modern version of GCC you shouldn't need to do this - what is your GCC version?Bregenz
c++11 or any other version does not specify how you interact with the compler/tools. You'll just have to accept that on some platforms, you need to invoke the compiler with certain flags when you need certain features.Intricacy
@NeilButterworth gcc version 7.1.1 20170622 (Red Hat 7.1.1-3)Gelatin
"Isn't C++11 supposed to abstract me away from platform specific details" C++11 abstracts your code away from platform specific details, which means that if you follow the rules your sources will be trivially compilable with any other conforming compiler; the build system remains ugly as always.Siddra
@MatteoItalia The compiler should be responsible for propagating library dependencies of its own implementation details. I ran into the same thing on GCC 8.3 on RHEL7: now I have to guess at my compiler's implementation and link additional libraries accordingly.Field
Possible duplicate of #8650328 ?Field
F
2

According to GCC's concurrency page, it's necessary to provide additional options to the compiler based on the features being used. You can verify that your version of GCC's threads rely on POSIX threads:

$ gcc -v 2>&1 | grep "Thread model"
Thread model: posix

See this bug report for a justification for the behavior:

The problem is that not all targets need -pthread, or some which do need it spell it differently, and not all platforms define _REENTRANT when the option is used, so there's no reliable way to do what you're asking for.

Field answered 17/3, 2020 at 20:15 Comment(1)
That doesn't really answer the question IMHO. The standard library should not require you to specify any other libraries to link against.Epidemiology
J
2

I am moving pthread to std:thread in C++11 and have encountered the same phenomenon you've been met, and I found this artical -- it may be the proper answer: https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread#

A quick conclusion: It depends on the version of glibc. glibc with versions prior to 2.34 will require the -lpthead flag even the code does not use pthread explicitly.

To check the version of glibc we can use ldd --version command, on my Ubuntu 20.04, it returns like this: ldd (Ubuntu GLIBC 2.31-0ubuntu9.9) 2.31, so I still have to add the -lpthread flag to use std:thread.

Jair answered 21/7, 2022 at 3:27 Comment(0)
C
0

pthread is an industry standard over the OS specific threads, using the OS specific calls.

std::thread is an abstraction in C++ that could be implemented using pthread or the OS's native threads. But to make it work on as many OS's as possible fast the std-library implementer could just implement it in posix as they should be good to go on all compliant OS's.

There are exceptions, some windows only std-library uses windows native threads instead.

Crackup answered 29/10, 2017 at 7:21 Comment(3)
That's all fine, but why should the user have to link against anything explicitly when only using standard library constructs? It's GCC's linker's business to sort out what to link against, so that everything in the standard library can be used.Epidemiology
@Epidemiology But the linker doesn't know your using std, your program could have been some fortran program that is being linked or it could already be included in one of the libs your including so extra work to find out what. Or you could wish to use another thread library to link against. It would be nice if the linker could read my mind and then link what I was thinking, but we have to wait a bit more for that.Crackup
But my program didn't come from Fortran. I was using g++ for compiling and for linking. At least when that's the case, it should make sure the linker is referred to the appropriate libraries.Epidemiology

© 2022 - 2024 — McMap. All rights reserved.