在ctor / dtor中启动/停止线程还是更好用start()/ stop()?

时间:2010-02-15 10:14:28

标签: c++ multithreading

我有一个内部使用工作线程的类。目前,ctor启动线程,dtor停止(并等待)它。这被认为是好的代码吗?我认为最好为此目的使用单独的start() / stop()函数。

其中一个问题是停止和等待线程可能会抛出异常,这在dtor中是不好的。

你会给我什么建议:

  1. 保持代码不变,只需捕获并记录dtor中的异常
  2. 使用start() / stop(),让客户端处理异常并删除dtor中的线程(并发出关于不干净关闭的警告等)

3 个答案:

答案 0 :(得分:4)

我可能不会在构造函数中启动线程,而是启动函数。如果工作线程对用户基本上是不可见的,那么它可能没什么区别,并且从构造函数开始可能会更好。但是如果用户以任何方式与工作线程交互(例如,他们的代码在其中运行),那么最终有人需要在创建对象之后但在线程运行之前设置一些状态。墨菲定律保证它; - )

我会在析构函数中停止它,并捕获并记录异常。如果用户可能需要知道停止的结果(例如,如果失败意味着工作线程可能没有完成其工作),那么还有一个停止功能,他们可以选择调用以获取该信息。 / p> 顺便说一下,在构造函数中启动一个线程也有一些技术问题。新线程可能会在构造函数在旧线程中返回之前运行。如果它访问其所有者对象(例如报告结果),则可以访问未完全构造的对象。这通常很容易解决,直到你从原始类继承。现在线程在派生类构造函数运行之前启动,这可能会导致各种麻烦。因此,如果您在构造函数中启动一个线程,并且该线程可以直接或间接访问该对象,请注意并留下大量警告。

答案 1 :(得分:1)

我不认为这两个选项是相互排斥的。我就是这样做的:

{
     mythread worker1; // starts
     mythread worker2(false); // doesn't start
     worker2.start();

     worker1.stop(); 

} // dtor. of worker2 stops it, dtor. of worker1 does nothing

答案 2 :(得分:0)

取决于类的语义。如果内部需要一个线程,最好在没有外部干预的情况下启动/停止线程。

好的方面可能是使用线程池,即重用前一个类实例丢弃的线程。