As a programming exercise I thought it would be fun to try to write a program which uses multiple threads the generate a random number. This method would introduce the "chaos" of the OS scheduler to add randomness.
The idea of 32 threads is that each thread will set a single bit of a number (left shift and 'or' with a random 0/1). They each generate the random bit from a Mersenne Twister engine and just 'and' with 1. EDIT: As Jarod42 pointed out, each thread cant share the same random engine. Assume each thread owns it's own engine.
std::mt19937 eng(/*some std::seed_seq to initialize*/);
At this point, I will describe my ideas towards implementation.
One option is to launch the threads each time the function is called.
unsigned int GetRandom() {
std::vector<std::thread> myThreads;
std::mutex numMutex;
unsigned int num = 0;
auto BitSetFunction = [&](){
std::lock_guard<std::mutex> numLockGuard(numMutex);
num <<= 1;
num |= eng() & 1;
};
for (int i=0; i<32; ++i) {
myThreads.emplace(myThreads.end(), BitSetFunction);
}
for (std::vector<std::thread>::iterator it=myThreads.begin(); it!=myThreads.end(); ++it) {
(*it).join();
}
return num;
}
However the problem I suspected, and sometimes see, is that the creation of the thread is usually slower than the actual locking, setting of the bit, and unlocking. If that is the case the threads will just execute in order and it wont be as interesting. Also the overhead of creating threads for every call to get a random number is huge (I'm assuming).
Is there a more clever way? I thought of creating an object and from it's construction the threads are launched and always running but waiting on a condition variable to know when to crank out a new random number. The problem I hit there was on the destruction of the object, the threads are also destroyed and throw errors because they're still executing.
I'm just curious to hear some other ideas.