作为一个编程练习,我认为尝试编写一个使用多个线程生成随机数的程序会很有趣。这种方法会引入操作系统调度程序的“混乱”以增加随机性。
32个线程的想法是每个线程将设置一个数字的一位(左移和'或'与随机0/1)。它们每个都从 Mersenne Twister 引擎生成随机位,并且只用 1 进行“和”。编辑:正如 Jarod42 指出的,每个线程不能共享相同的随机引擎。假设每个线程都拥有自己的引擎。
std::mt19937 eng(/*some std::seed_seq to initialize*/);
在这一点上,我将描述我对实施的想法。
一种选择是在每次调用函数时启动线程。
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;
}
然而,我怀疑并且有时会看到的问题是线程的创建通常比实际的锁定、位设置和解锁要慢。如果是这种情况,线程将按顺序执行,并且不会那么有趣。此外,为每次调用创建线程以获得随机数的开销也很大(我假设)。
有没有更聪明的方法?我想创建一个对象,并从它的构造中启动线程并始终运行但等待条件变量以知道何时生成新的随机数。我遇到的问题是对象的破坏,线程也被破坏并抛出错误,因为它们仍在执行。
我只是想听听其他一些想法。