【问题标题】:Best way to handle job cancellation on thread在线程上处理作业取消的最佳方法
【发布时间】:2014-05-01 17:53:49
【问题描述】:

我写了一个简单的作业队列,它使用一个线程一个接一个地运行队列中的作业。线程本身来自池,因此只要作业队列对象存在,它的生命周期就会持续。作业从队列中弹出,然后在作业上调用 run(),然后在完成后将其丢弃。

我想知道我可以使用什么样的范例来中止工作。天真的方法是有一个我定期检查的中止标志。问题是由于 I/O 阻塞或其他一些计算量大的任务,一些作业需要一段时间。

我认为的另一个选择是完全终止线程。这是一个潜在的肮脏和容易出错的解决方案。

还有其他方法吗?

编辑:由于我在 C++ 领域,有没有办法将异常注入另一个线程?它会立即中断执行并返回主线程。我认为这将是理想的。

【问题讨论】:

  • 如果您真的看不到使用上述“flag”-à 方法的任何可能性,请查看pthread_cancel()
  • 要么使用标志解决方案,要么运行一个可以终止的单独进程。杀死一个线程是一个坏主意。见drdobbs.com/parallel/interrupt-politely/207100682
  • @alk: AFAIK,使用pthread_cancel() 也会导致线程本身退出。我试图避免这种情况。基本上,我想要一种取消正在运行的作业的方法,以便可以使用干净的作业队列。一种方法是重新创建线程。
  • 请问“立即中断执行”(来自您的编辑)和“导致线程本身退出”(来自您的评论)?
  • @alk:即使在调用clean() 之后,作业队列对象仍应像作业队列一样工作,其中作业被中止并且队列被清空。中断执行会中止作业,但让线程继续运行(阻塞并等待新作业)。只有当作业队列对象被销毁时才会退出线程。我也愿意接受有关此设计的建议。

标签: c++ pthreads jobs


【解决方案1】:

取决于您使用的线程的实现,可能有不同的方式来操作“中止标志”。我愿意考虑 boost.threads 和 boost.interruption_points。 UPD:这会在线程中注入异常,如果它在中断点,如你所愿。

但如果你有一大块不可分割的繁重计算,那么,我相信,从意识形态上讲,它必须完整地完成。想一想,如果您在该块内看到任何可以停止它的“时刻”,那么您可以将该块拆分为部分,在那些时刻插入“中止标志”。 所以,如果是单体块,就不可能有这样的时刻。所以你不能以正常的方式中断计算。所以你必须等待他们完成。

但是你可以避免等待问题,如果你不是在分离的线程中计算你的重块,而是在分离的进程中。然后你可以杀死它而不必担心弄脏你的主进程内存,如果需要,你甚至可以让它计算它需要几个小时,在你的主进程在几分钟前关闭之后,如果需要,然后默默地死掉。没问题。

【讨论】:

    猜你喜欢
    • 2017-06-22
    • 2014-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-25
    • 2012-12-05
    相关资源
    最近更新 更多