我有一个内部使用工作线程的类。目前,ctor启动线程,dtor停止(并等待)它。这被认为是好的代码吗?我认为最好为此目的使用单独的start()
/ stop()
函数。
其中一个问题是停止和等待线程可能会抛出异常,这在dtor中是不好的。
你会给我什么建议:
start()
/ stop()
,让客户端处理异常并删除dtor中的线程(并发出关于不干净关闭的警告等)答案 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)
取决于类的语义。如果内部需要一个线程,最好在没有外部干预的情况下启动/停止线程。
好的方面可能是使用线程池,即重用前一个类实例丢弃的线程。