【问题标题】:Throw an error if executed in a parallel section?如果在并行部分执行会引发错误?
【发布时间】:2013-01-28 00:18:16
【问题描述】:

在我的代码中,我有一个使用静态随机引擎生成器运行的函数,如果用户尝试从与主线程不同的线程调用此函数,我希望能够引发错误。

例如,如果您考虑以下功能:

void f()
{
    if (/* SOMETHING */) {
        throw std::future_error("ERROR = f() : cannot be executed in parallel");
    }
}

/* SOMETHING */ 是什么?

【问题讨论】:

  • 实现一个最初锁定的信号量,你就完全摆脱了这个问题。但是不要忘记在并行块终止后释放它。
  • /* 一些东西 */ == IsSameThread(Main,Me),以任何方便的方式实现。

标签: c++ exception c++11 parallel-processing stdthread


【解决方案1】:

我在线程方面不是很有经验,但不知何故我很想按照单例/其他设计模式做一些事情。

话虽如此,我不认为这个想法很优雅,我不知道你为什么要这样做,所以我不知道如何提出任何替代方案......

虽然我确实认为可以在 main 中创建一个单例,这样就可以防止任何从其他线程调用 f 的尝试。

单例通常被误用,所以...我会小心的。

【讨论】:

    【解决方案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");
        }
    }
    

    【讨论】:

      【解决方案3】:

      一个更好的解决方案是让您的随机数检索线程安全。

      这可以通过以下两种方式之一完成:

      1. 在检索随机数时获取mutex
      2. 为任何需要生成随机数的线程提供自己的随机对象。

      让我们谈谈#1。既然您建议包装您的调用以获取随机数,那么wrap those calls with a mutex 并不太牵强。我们不是简单地在运行时将问题呈现给用户(这通常是一个非常糟糕的开发选择),而是解决了这个问题。唯一的缺点是我们减慢了对随机数生成器的调用速度——这可能是可以接受的,但如果不是……请选择选项 #2。

      而且,对于 #2... 你说这是一个 静态 随机数生成器。也许这意味着您不能再复制它,但无论如何这值得一提。 randsrand 是这样的。但是,如果您使用的是 C++11 的 std::uniform_int_distribution 之类的东西,那么为每个线程创建一个副本应该没有问题。 (如果找不到放置每个线程副本的好地方,可以考虑std::thread_local。)

      【讨论】:

        猜你喜欢
        • 2011-09-15
        • 1970-01-01
        • 2020-12-17
        • 2015-12-26
        • 2015-11-05
        • 1970-01-01
        • 2021-04-15
        • 2019-03-03
        • 2020-07-29
        相关资源
        最近更新 更多