在我的代码中,我有一个使用静态随机引擎生成器运行的函数,如果用户尝试从与主函数不同的线程调用此函数,我希望能够抛出错误。
例如,如果您考虑以下功能:
void f()
{
if (/* SOMETHING */) {
throw std::future_error("ERROR = f() : cannot be executed in parallel");
}
}
什么是/* SOMETHING */
?
答案 0 :(得分:2)
我在线程方面不是很有经验,但为什么我很想在单身人士/其他设计模式上做点什么。
话虽这么说,我不相信这个想法非常优雅,我不知道你为什么要这样做,所以我不知道如何建议任何替代方案......
虽然我确实认为可以在main中创建单例,但是任何尝试从其他线程调用f都将被阻止。
Singleton经常被误用,所以......我要小心。
答案 1 :(得分:2)
虽然我不认为你想要实现的是非常优雅的(锁定或保存你的随机引擎生成器的每个线程的状态,例如使用线程本地存储,可能会更好),这里是你问的解决方案为:
static const auto mainThreadId = std::this_thread::get_id();
void f()
{
if (std::this_thread::get_id() != mainThreadId) {
throw std::future_error("ERROR = f() : cannot be executed in parallel"
"/from a thread other than the main one");
}
}
答案 2 :(得分:1)
一个更好,更好,更好的解决方案是让您检索随机数线程安全。
这可以通过以下两种方式之一完成:
让我们谈谈#1。由于您建议将您的来电包裹起来以获取随机数字,因此它不会过于牵强wrap those calls with a mutex。我们不是简单地在运行时向用户提出问题(这通常是一个非常糟糕的开发选择),而是解决了问题。唯一的缺点是我们放慢了对随机数生成器的调用 - 这可能是可以接受的,但如果它不是......在选项#2上。
并且,对于#2 ... 您说这是静态随机数生成器。也许这意味着你不能再制作它的副本,但无论如何这都值得一提。 rand
和srand
就像这样。但是,如果你使用像C ++ 11 std::uniform_int_distribution
这样的东西,你应该没有问题为每个线程创建一个副本。 (如果找不到放置每个帖子副本的好地方,也许可以考虑std::thread_local
。)