05 C++ Threads
05 C++ Threads
#include <mutex>
using std::mutex;
std::mutex
// m is shared among all threads
mutex m;
// This is a place where multiple threads can be
#include <future>
Creating a std::future
• There are a few ways in C++ to create a future, but we
will only focus on ONE
• std::thread allowed us to create a thread which we know
would run asynchronously to our main thread
• We want to asynchronously run an get a future
• Introducing: std::async
using std::async;
// similar to thread
std::future – “get()”-ing the
result
int rand_between (int low, int high) {
static std::minstd_rand rng{0};
return low + rng () % (high – low);
}
vector<thread> threads;
for (int tid = 0; tid < numThreads; ++tid) {
threads.emplace_back ( /* args to thread ctor */ );
}
Managing ALL THE FUTURES
– Wait/Cleanup
• Wait for them to finish
// Alternatively
std::for_each (threads.begin(), threads.end(), thread::join);
Managing FUTURES –
CREATION
• Creating a bunch of asyncs
• And have them do a work
vector<future<results>> threads;
for (int tid = 0; tid < numThreads; ++tid) {
threads.emplace_back (std::launch::deferred,
/* args to thread ctor */ );
}
Managing FUTURES –
Wait/Cleanup
• Wait for them to finish
Usage:
thread t1 (populate, ref(vec), ref(mut), K, tid);
Bonus: C++ Lambdas
// vec, mut, and K are actual parameters
auto populate = [&vec, &mut, K] (int tid) {
for (int i = 0; i < K; ++i) {
mut.lock();
vec.push_back(tid);
mut.unlock();
}
};
Bonus C++ Lambdas:
vector<int> vec;
mutex mut;
int K = …;
auto populate = … /* lambda definition */;
for (int tid = 0; tid < P; ++tid) {
threads.emplace_back (populate, tid);
}
Bonus: C++ Lambdas
• Before
void populate (vector<int>& v, mutex& m, int K, int tid);
threads.emplace_back(populate, ref(vec), ref(mut), K, tid);
• After
auto pop = [&vec, &mut, K] (int tid) {
return populate (vec, mut, K, tid);
};
threads.emplace_back(pop, tid);