C++11 Std::Threads VS Posix Threads

C++11 std::threads vs posix threads

If you want to run code on many platforms, go for Posix Threads. They are available almost everywhere and are quite mature. On the other hand if you only use Linux/gcc std::thread is perfectly fine - it has a higher abstraction level, a really good interface and plays nicely with other C++11 classes.

The C++11 std::thread class unfortunately doesn't work reliably (yet) on every platform, even if C++11 seems available. For instance in native Android std::thread or Win64 it just does not work or has severe performance bottlenecks (as of 2012).

A good replacement is boost::thread - it is very similar to std::thread (actually it is from the same author) and works reliably, but, of course, it introduces another dependency from a third party library.


Edit: As of 2017, std::thread mostly works on native Android. Some classes, like std::timed_mutex are still not implemented.

boost::thread vs std::thread vs pthread

  • std::thread
    • Pro: Is standard; guaranteed to be on all conforming platforms.
    • Con: Requires C++11, so it cannot be used with ancient compilers. Only basic, lowest common denominator features. However, platform specific features can still be used through std::thread::native_handle.
  • boost::thread
    • Pro: Is cross platform, is supported on ancient compilers.
    • Con: Is not standard; requires an external dependency. Similar feature set as standard threads.
  • pthread:
    • Pro: Has more features such as schduling policy.
    • Con: Is only on POSIX systems, which excludes Windows. Non-RAII interface.

When should one implementation be used over the others?

std::thread is often a good default. If you need features of pthread that are not in the standard, you can use them with the help of std::thread::native_handle (with the implications on the portability that come with it). There's no reason to use pthread directly otherwise (that I know of) in C++.

boost::thread can be used if you need ancient pre-C++11 support, to remain portable to other systems.


Note that std::thread itself doesn't need to be used directly. The standard has useful abstractions such as std::reduce, std::packaged_task, std::async, parallel execution policies for algorithms etc.

Is C++11's std::thread compatible with POSIX semaphores?

The C++ standard library will implement std::thread as a wrapper over pthreads on POSIX systems, so using <semaphore.h> would be fine. Semaphores are usually implemented regardless of the specific threading interface, though the C standard library may do some book-keeping at the same time using pthreads.

For this reason, calling sem_wait() from a thread (whether it be a pthread_t or an std::thread) will have the same effect, though it may be better to just use pthreads, as they would be the most "compatible", especially since you are only targeting POSIX systems anyway.

The advantage of c++11 threads

Besides being much more portable, C++11 threads also provides other benefits:

  • allows passing arguments (and more than one) to the thread handler in a type safe way. pthread_create passes a single void*, whereas with std::thread you get compile time errors if something is wrong instead of runtime errors
  • the thread handler can be a lambda
  • a std::thread is an object, not a pointer, which makes managing object lifetimes easier, and reduces risk of dangling pointers, especially if combined with std::unique_ptr or std::shared_ptr if pointer juggling is even needed.

Those are the immediate benefits that come to mind.

As for standard library vs language spec: they are both part of the same standard, so they are both considered "C++11". Note that std::thread can not be implemented in C++03, since move semantics is new in C++11 and std::thread implements move.

Mixing C++11 std::thread and C system threads (ie pthreads)

The C++ standard doesn't specify how C++ threads interact with any other thread library, but in general I would expect a C++ implementation to use the underlying system thread library, so your usage should be safe.

Being able to use a third-party library that uses the system thread library locking primitives is such a common use case that it should be expected to work (otherwise C++ threading support would be almost useless in lots of real-world situations). As Pete points out, anything involving thread handles/ids can be more tricky (but shouldn't be required from reading your question).

C++11: Is std::thread on linux depending on pthread library?

Use ldd myExecutable on compiler output to find out.

Both libstdc++ and libc++ apparently use pthreads, but they are not required to do that. Evidence of it can be found in native_handle methods documentation here and here. The documents say:

Accesses the native handle of *this.

The meaning and the type of the result of this function is implementation-defined. On a POSIX system, this may be a value of type pthread_cond_t*. On a Windows system, this may be a PCONDITION_VARIABLE.

and

Returns the implementation defined underlying thread handle.

Is it really impossible to suspend two std/posix threads at the same time?

I want to suspend them when the CPU temperature rises above a threshold.

In general, that is putting the cart before the horse.

Properly designed hardware should have adequate cooling for maximum load and your program should not be able to exceed that cooling capacity.

In addition, since you are talking about Turbo, we can assume an Intel CPU, which will thermally throttle all on their own, making your program run slower without you doing anything.

In other words, the tasks take too long to complete

You could break the tasks into smaller parts, and check the semaphore more often.

A separate control thread occupies the control semaphore for a few milliseconds

It's really unlikely that your hardware can react to millisecond delays -- that's too short a timescale for anything thermal. You will probably be better off monitoring the temperature and simply reducing the number of tasks you are scheduling when the temperature is rising and getting close to your limits.

I've now implemented it with pthread_kill and SIGRT.

Note that suspending threads in unknown state (whatever the target task was doing at the time of signal receipt) is a recipe for deadlocks. The task may be inside malloc, may be holding arbitrary locks, etc. etc.

If your "control thread" also needs that lock, it will block and you lose. Your control thread must execute only direct system calls, may not call into libc, etc. etc.

This solution is ~impossible to test, and ~impossible to implement correctly.

How do OpenMP, MPI, POSIX threads, std::thread, boost::thread correlate?

OS provides threads (syscalls to create new threads; scheduling services).

Unix libc has wrapper around OS threads with lot useful functions (like mutexes, cond vars, etc). Usually external interface of such system libraries is "POSIX threads" (functions named pthread_*): http://en.wikipedia.org/wiki/POSIX_Threads

Windows has its own hard-to-use threading API (WINAPI's CreateThread, etc). But there are wrappers around Windows API to get something like POSIX threads api (e.g. there is such libraries for mingw32 and cygwin; check wikipedia section)

C++11 std::thread, boost's boost::thread are just modern OS-independent wrappers around system threading API. They are used to create portable programs which can be compiled on any supported platform, without creating #ifdef hell and/or writing own custom wrappers around system threading library. If your are creating new program, consider using this way.

There are several other threading wrappers, e.g. included in graphic libraries like QT or GTK+.

OpenMP implementations has internal support library (for example, gcc has libgomp) which uses system/libc threading APIs, for example libgomp uses POSIX threads. Some implementations may also include user-space thread switching via assembly (M:N threading model).

MPI has no thread library inside. MPI is used to create several processes and setup communication between them. But when MPI is used in multithreaded programs, it will use some threading API to do synchronization. For example, MPICH will use pthreads on unix.



Related Topics



Leave a reply



Submit