这是我问题的延续:Thread creation inside constructor
现在我已经成功地在构造函数中创建了一个线程,我知道它必须被连接,因为我正在开发一个API,我对主函数没有控制权,所以我不能在那里连接它。
考虑到类的示例化对象将具有应用程序的生命周期,在类析构函数中加入线程是否正确?
这是我问题的延续:Thread creation inside constructor
现在我已经成功地在构造函数中创建了一个线程,我知道它必须被连接,因为我正在开发一个API,我对主函数没有控制权,所以我不能在那里连接它。
考虑到类的示例化对象将具有应用程序的生命周期,在类析构函数中加入线程是否正确?
4条答案
按热度按时间kmb7vmvb1#
你可以这样做。但是,你是真的对启动一个新线程的 * 机制 * 感兴趣,还是对异步执行某个任务的 * 效果 * 感兴趣?如果是后者,你可以转向更高级别的
async
机制:bar
,你不关心自己管理线程--让库来处理。future
放入成员中。get
代表未来。km0tfn4u2#
您已经遇到了C++ RAII的缺点之一:析构函数不能轻易地报告错误,析构函数也不能优雅地失败,因为它们没有返回值,抛出异常是bad idea。
那么如果另一个线程没有响应停止请求,析构函数能做什么呢?它可以等待更长时间,或者猛烈地破坏另一个线程,或者让它继续运行,这些都不是很好的选择。然后它可以忽略这种情况,只是记录它,或者抛出异常,尽管应用程序有立即终止的风险,这也不是一个很好的选择集。
所以你至少有三个选择
对于线程,无法立即终止的线程通常可以被视为类似于segfault的编程错误,因此您可以选择使用helpful终止应用程序(对开发人员)诊断消息(上面的第二个要点),或者让程序挂起(上面的第一点)。但是这有点冒险,因为如果继续下去,你需要创建一个不能很快终止的线程(它正在执行阻塞系统调用,或者它必须通知网络连接的另一端,这可能会很慢),在锁定设计之前考虑如何解决这个问题是一个好主意。
blpfk2vs3#
当然,你可以这样做。只是要确保线程将存在,否则你的程序将永远挂在该联接。
smtd7mpg4#
我提出了一个线程模式,我发现它可以处理C++中关于在类中运行线程的所有奇怪情况。
http://chrisd.nl/blog/how-to-run-threads/