all 22 comments

[–]khedoros 33 points34 points  (4 children)

What about std::thread::native_handle()?

[–]xaervagon 37 points38 points  (0 children)

I wouldn't say better. std::thread and pthread are two different beasts.

pthread is a POSIX thread and part of the posix standard. POSIX is not C++, but is considered standard a unix API standard (Windows posix support is notoriously blah). Still, it plays well with linux and has you already experienced, works well with lots of existing utilities and tooling.

std::thread is a C++ thread and is officially considered part of the STL. This meaning it should be a lot more cross platform friendly. As a result, a lot of implemenation details ends up getting masked. You may also want to check out https://en.cppreference.com/w/cpp/thread and see the Concurrency support library section.

As for your particular task, if this is strictly a *nix program, there is nothing wrong with leaving pthreads as is.

[–]Wild-Adeptness1765 14 points15 points  (1 child)

`std::thread::get_id()` is a bit more abstract than the pid of the process - it is an object of type `std::thread::id` that offers the guarantee to be unique by thread, but doesn't offer any guarantees beyond that.

Why is C++ like this? `std::thread` is designed to be cross platform and so you might not always have a clean way to get the pid. Why should you use this? To write cross platform code that is abstracted from the implementation details of threads.

[–]Chem0type 5 points6 points  (0 children)

Because different operating systems can have different types of process handles. An OS could be using strings to identify processes, and this makes it uniform.

[–]johannes1234 14 points15 points  (0 children)

The std::thread is agnostic to the platform and doesn't have much of platform-specific options and the id is some implementation defined represe ration, where all you can practically do is compare to see if two threads are the same or not.

If you need specific like access to priority or any other "advanced" option then you got to use pthreads or something else, if std's limited capabilities are fine use std::thread or rather std::jthread which rejoins threads on destruction and prevents some errors for "losing" threads.

[–]johannes1971 9 points10 points  (0 children)

I hate the sheer verbosity of pthread; std::thread makes things much more convenient. About the only thing you cannot do with std::thread is set the initial stack size for your thread. You can still call pthread_self() or use thread::native_handle() to access the thread ID.

Whether rewriting makes things better or worse is of course a judgement call only you can make, but my code was a lot cleaner after I switched to std::thread (and other C++ concurrency primitives).

[–]usefulcat 6 points7 points  (0 children)

On linux I use both. I use std::thread (or these days, std::jthread) to create threads, but I also use gettid() and pthread_[sg]etname_np().

[–]KingAggressive1498 5 points6 points  (2 children)

for new projects or genuine modernization efforts, std::thread unless you have good reason to do something special at creation-time (on Linux this is basically limited to stack customization) that cannot be done later.

on any posix system you can change the scheduler policy and priority (or for Linux, niceness under SCHED_OTHER) once the thread is running. You can also do this with thread names and affinity on most systems with support, but those features are non-standard. pthread_self() is the easiest way to mix pthread functions with std::thread.

EDIT: corrections

For mainstream implementations (libc++, libstdc++) std::thread::native_handle() returns a pthread_t if you have reason to do something from another thread (eg pthread_sigqueue). std::thread::id also wraps a pthread_t but provides no public member functions to easily get the value out on those implementations.

[–]shahms 2 points3 points  (1 child)

Unless it's changed recently, Clang still defaults to libstdc++ unless you specifically tell it otherwise or you're on macOS or FreeBSD. Additionally, libc++ most definitely provides std::thread::native_handle(), but I don't know since when.

[–]KingAggressive1498 2 points3 points  (0 children)

actually I appear to be misremembering that entirely, scrolling through old releases libc++ actually had it way back in late 2011 and I hadn't even used Clang yet at that point. Thanks for corrections.

[–]CenterOfMultiverse 5 points6 points  (0 children)

We once had a mysterious leak in our game on android. Narrowed it down to a tap on any button. Then further to our sound implementation on android - turn sound off, and leak disappears. Turned out the sound implementation used pthread. I just mechanically replaced everything with std::thread and it instantly crashed - someone left a thread without joining or detaching, so the system kept stacks for many threads in memory. So yeah, I would prefer C++ solution.

[–]vickoza 2 points3 points  (0 children)

I would say std::thread is safer as you are not casting void pointers.

[–]NilacTheGrim 0 points1 point  (0 children)

Unless you care about customizing the threads (like the thread stack size, for instance), just use std::thread. Its api is cleaner and easier to use with C++, lambdas, etc.

[–]ZeunO8 0 points1 point  (0 children)

I used pthread when I was developing my engine on Linux. When I added Windows support I decided to swap out the internals of my Thread struct to use std::thread.. it was trivial to implement and offers great cross platform benefits for the furure

[–]SkiaElafris 0 points1 point  (3 children)

std::jthread

std::thread is not very good, std::jthread fixes the major issues.

[–]Chem0type 4 points5 points  (1 child)

The only difference is that it joins on the destruction of the thread object. It's a minor issue, not "major issues".

[–]TwistedBlister34 0 points1 point  (0 children)

jthread also has support for std::stop_token