我有几个线程池,我希望我的应用程序处理取消操作。
为此,我实现了一个共享操作控制器对象,我在每个调用的线程池工作器函数的各个位置进行轮询。
这是一个很好的模型,还是有更好的方法呢?
我只是担心在整个代码中散布所有这些operationController.checkState()。
答案 0 :(得分:5)
是的,这是一个很好的方法。 Herb Sutter有nice article将其与替代品进行比较(更糟糕的是)。
答案 1 :(得分:1)
通过任何类型的异步取消,您将不得不定期轮询某种标志。必须将事物保持在一个共同状态是一个根本问题。如果你只是在它正在做的事情中间杀死一个线程,那么迟早会发生坏事。
根据您实际执行的操作,您可以忽略操作的结果而不是取消它。你让操作继续,但不要等到它完成,不要检查结果。
如果您确实需要停止操作,那么您将需要在适当的位置进行轮询,并进行必要的清理。
答案 2 :(得分:1)
这是一个很好的方法。
另一种可能的方法是,如果有一些其他子程序[s],线程仍然会定期调用,检查该子程序并抛出异常(被捕获在线程的顶部),假设“取消“可以被视为例外,并假设线程执行的代码是异常安全的。
答案 3 :(得分:1)
我不会这样做,检查共享对象。
我很可能会为每个线程对象提供一种取消自己线程内执行的方法,无论是事件,线程安全状态变量还是其他什么。
共享操作控制器的问题在于,从我的观点来看,逻辑是相反的,当它不控制任何东西时,为什么称它为“控制器”?
对我来说,操作控制器应该重新获取取消订单,然后选择适当的线程并发出信号停止。如果你知道我的意思,那将是一个正确的“指挥链”。你这样做的方法就是在线程中引入一种不自然的行为,而不是“服从”命令停止,而是每次检查他的“上司”是否“写了一些订单”。不知怎的,它感觉不对。
另外,如果你将来只停留一些“部分”线程怎么办?如果你想包含一些高级逻辑以便线程只在条件下停止怎么办?然后你将不得不重写每个线程中的代码来处理这个条件。
因此,我将为每个线程提供一种方法,以便能够处理信号,例如使用具有FIFO结构的Command Pattern。
(顺便说一句,我意识到他们是线程池工作者,而不是实际的线程类,但我认为每个工作人员都必须通知单独停止,而不是反过来。)
答案 4 :(得分:0)
在类似的情况下,我使用了一个事件,非自动重置,所有线程都可以查看该事件。与轮询非常相似,除非你的线程有时会阻塞,它们也可以为“停止”事件而休眠。 (在Windows上更容易。)
/ L