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 singlevoid*
, whereas withstd::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 withstd::unique_ptr
orstd::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
andSIGRT
.
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
Parse Int or Double Using Boost Spirit (Longest_D)
Are the "Usual Arithmetic Conversions" and the "Integer Promotions" the Same Thing
Writing a Matrix into a Single Txt File with Mpi
Qt MACro Keywords Cause Name Collisions
Setting Pointer to Arbitrary Dimension Array
Timestamps for Embedded System
Why Is My Double or Int Value Is Always 0 After Division
C++ Convert from Lpctstr to Const Char *
Why Does Sizeof(Int) Vary Across Different Operating Systems
Stoi and Std::To_String on Mingw 4.7.1
Image Retrieval System by Colour from the Web Using C++ with Openframeworks
C++ Regex for Overlapping Matches
Glut Deprecation in MAC Osx 10.9, Ide: Qt Creator
C++ Static Const Access Through a Null Pointer