C++11 multithreading tutorial
solarianprogrammer.com
solarianprogrammer.com
Here's an example: C++11 has timed wait on mutex and condition variables, using std::chrono time stamps for absolute and relative times. Most threading wrappers don't provide this but it's available in pthreads (and I guess Windows API too). Not only does C++11 provide this but it plays along very nicely with the clocks in chrono and you can use it with different time sources, like the monotonic system clock.
I've used both when building multithreaded "main loops" for game/simulation purposes. Using C++11 threads + chrono is a lot nicer to the programmer than doing the same with posix pthreads in C. The biggest improvement is exception safety, type safety and rich types for clocks and timestamps come second.
#pragma omp for ...
Disclaimer: I haven't found that OpenMP is too useful outside of pure computation, but it is worth mentioning if all you want to do is run loops in parallel.Current spec (pdf): http://openmp.org/mp-documents/OpenMP3.1-CCard.pdf
[1] http://solarianprogrammer.com/2011/10/07/great-book-about-c1...
One of the Amazon one-star reviews says, "For a book of this size, I would have expected extensive coverage of key C++ concepts. However, I am very unsatisfied with this book, since the coverage of C++ is superficial at best."
Sounds exactly like a Wrox book.
For the definitive reference I would wait for the 4th edition of "The C++ Programming Language" by B. Stroustroup.
- Use lambdas
- Use std::scoped_ptr or std::shared_ptr
- Use std::vector instead of C Array
- Use references instead of pointers
That would prevent unnecessary pitfalls.
AFAIK, it should be possible to put threads (non-copyable but movable) to a vector in C++11. Of course, then the vector will not be copyable (but it will be movable). I think I've even done it, but I used GCC, which has had pretty good C++11 support for quite a while now. (sorry, I'm too lazy to verify)
One way I was thinking about it was std::vector<std::shared_ptr<std::thread>>
Additionally, this sucks:
#define NUM_THREADS 10
In C++03 you can write
static const int num_threads = 10;
Which is much better.
And instead of:
for(int i=0;i<NUM_THREADS;i++){ t[i] = thread(call_from_thread,i); }
Better use std::generate.
I may look like I'm nitpicking but I think it's paramount in a tutorial to have all details really, really right so that it may trigger other questions and go in depth about why things are better a way or the other.
Of course it works, since std::thread is movable but non-copyable, std::vector<std::thread> will be movable but non-copyable too. So the compiler type checking will make sure it's not copied anywhere.
This works like a charm (with GCC 4.7-ish from git):
#include <thread>
#include <vector>
#include <iostream>
#include <algorithm>
int main()
{
std::vector<std::thread> threads;
for(int i = 0 ; i < 10 ; ++i)
threads.push_back(std::thread([=]() { std::cout << i << std::endl; }));
std::for_each(threads.begin(), threads.end(), [](std::thread& thread) { thread.join(); });
}
>> Better use std::generate.I used to nitpick about not using std::algorithms when they're available, but I grew out of it. I figured out that std::algos are very limited (esp. in c++98), and while you can use them to do stuff, it usually takes a significant amount of brainpower only to reformulate your problem to be suitable for std::algorithms. There are so many situations where a good old loop will produce more readable code faster, so why bother with the standard algorithms if they're not a perfect fit?
Btw. has std::generate improved at all in C++11? It's one of the most limited algorithms in c++98.
That's true, but the final result generally ends up with less bugs and better thought out algorithms. It forces you to think "what problem am I currently trying to solve?"
- thread t[NUM_THREADS]; // since NUM_THREADS is constant
- std::unique_ptr<thread[]> t(new thread[NUM_THREADS])What about std::array?