合作/非抢先线程避免死锁?

时间:2010-03-26 06:45:28

标签: c# multithreading deadlock contextswitchdeadlock

任何创造性的想法,以避免在没有执行O / S Thread.Sleep(10)的情况下通过协作/非抢占式多任务处理产生或睡眠的死锁?通常,yield或sleep调用将回调到调度程序以运行其他任务。但这有时会产生死锁。

一些背景知识:

这个应用程序对速度有着巨大的需求,到目前为止,它与同行业的其他系统相比速度极快。其中一种速度技术是协作/非抢占式线程,而不是O / S线程上下文切换的成本。

高级设计优先级管理器,根据优先级和处理时间调用任务。每个任务执行一次“迭代”工作并返回以在优先级队列中再次轮到它。

非抢占式线程的棘手问题是,当您希望特定任务在工作中停止并等待来自其他任务的其他事件时,该怎么做才能继续。

在这种情况下,我们有3个任务,A B和C,其中A是必须同步B和C的活动的控制器。首先,A启动B和C.然后B产生所以C被调用。当C产生时,A看到它们都处于非活动状态,决定B运行的时间,但不是C的时间。好吧B现在停留在一个叫做C的收益率中,所以它永远不会运行。

2 个答案:

答案 0 :(得分:1)

我认为可能最简单的处理方法是将阻塞(一个决定它已经处理足够一段时间的线程)与阻塞(等待特定事件)分开。这使得为​​已经产生的线程留出时间相对容易,但是避免了尝试运行被阻塞的线程的死锁。通常,您希望对哪个线程阻塞其他线程进行拓扑排序,这样您就可以为其他线程等待的线程留出时间。这应该给出一个DAG - 图中的任何循环都表示死锁。

答案 1 :(得分:0)

嗯,意识到理想的解决方案是,如果C#语言支持真正的“延续”以覆盖整个堆栈并继续在以后停止的地方。

如果没有,我们正在进行自己的临时替换,允许这种情况下的任务将“isInterrupted”标志设置为true并返回 - 从而展开堆栈。

然后,当调度程序想要再次为该任务调度处理时间时,它将看到isInterrupted并跳过已经完成的处理,使用简单的if语句直接跳转到中断位置。

此致 韦恩