【问题标题】:Can Pthreads be created inside a constructor?可以在构造函数中创建 Pthreads 吗?
【发布时间】:2012-06-30 19:18:25
【问题描述】:

我想创建一个线程池。我有一个名为 ServerThread.cpp 的类,它的构造函数应该做这样的事情:

ServerThread::ServerThread()
   {
         for( int i=0 ; i<init_thr_num ; i++ )
         {
              //create a pool of threads
              //suspend them, they will wake up when requests arrive for them to process
         }
   }

我想知道在构造函数中创建 pthread 是否会导致任何应该避免遇到的未定义行为。

谢谢

【问题讨论】:

    标签: c++ multithreading constructor pthreads threadpool


    【解决方案1】:

    您当然可以在构造函数中执行此操作,但应该注意 Scott Meyers 在其 Effective/More Effective C++ 书籍中明确解释的问题。

    简而言之,他的观点是,如果在构造函数中引发任何类型的异常,那么您的半支持对象将不会被破坏。这会导致内存泄漏。因此,Meyers 的建议是使用“轻量级”构造函数,然后在对象完全创建后调用的 init 方法中完成“繁重”工作。

    此参数与在构造函数中创建 pthread 池并不严格相关(因此,您可能会争辩说,如果您只是创建它们然后立即挂起它们,则不会引发异常),而是关于如何做的一般考虑在构造函数中(阅读:良好实践)。

    另一个需要考虑的是构造函数没有返回值。虽然确实(如果没有抛出异常)即使线程创建失败,您也可以让对象保持一致状态,但管理来自 initstart 方法的返回值可能会更好.

    您也可以阅读this thread on S.O. 了解该主题,以及this one

    【讨论】:

    • 这与线程无关,Scott 的建议在很大程度上已被更高级的技术所取代:诸如将资源由基类或成员管理之类的事情,在进入之前就已经完全构建好了构造函数体。 (在这种情况下,线程池应该是一个成员,所以它的析构函数会在异常的情况下被调用。)
    • @James Kanze:在我的回答中,我已经指出了以下几点:“这个论点与在构造函数中创建 pthread 池并不严格相关”,而是与“良好实践”相关。此外,您在您的评论和您自己的回答中都确认建议使用一些特定的技术来正确处理这个问题。 init 方法,无论它多么古老或简单,都只是这些技术之一。无论如何,感谢您的评论。
    【解决方案2】:

    从严格形式的角度来看,构造函数实际上只是一个 功能与其他任何功能一样,应该没有任何问题。 实际上,可能存在一个问题:线程可能实际启动 在构造函数完成之前运行。如果线程需要一个 完全构造的ServerThread 运行,然后你在 麻烦——当ServerThread 是基数时,通常会出现这种情况 类,并且线程需要与派生类进行交互。 (这 是一个很难发现的问题,因为最常见的 使用线程调度算法,新线程通常不会 立即开始执行。)

    【讨论】:

      猜你喜欢
      • 2017-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-18
      • 1970-01-01
      • 2021-04-25
      相关资源
      最近更新 更多