技术开发 频道

WinCE陷进程死锁 马儿光吃草不快跑

  三. Windows CE线程死锁的解决方法

  (1)通过设计预防死锁

  当我们理解了线程死锁的原因,尤其是产生死锁的四个必要条件后,就可以最大可能地避免、预防和解除死锁。所以,在Windows CE的系统设计、进程调度等方面应注意不让这四个必要条件成立,避免进程永久占据资源。此外,也要防止进程在处于等待状态的情况下占用资源。在系统运行过程中,对进程发出的每一个资源申请都进行动态检查,并根据检查结果决定是否分配资源,若分配后可能发生死锁,则不予分配,否则予以分配。

  因此,在多任务、多线程应用程序开始编程之前就详细设计,避免线程死锁是最好的方法。例如,代码审查就是一个有效的方法之一,通过破坏四个必要条件中的一个或多个以预防系统发生线程死锁。

  (2)建立资源分配图避免死锁

  线程死锁产生与进程对资源的需求、进程的执行速度、资源的分配策略有关。如果无法通过设计来避免死锁,则应该建立资源分配图。通过仔细跟踪系统中的所有线程和它们锁定的共享资源,周期性地进行检查和维护资源分配图,及时发现循环等待的特征,从而识别潜在死锁。

  建立资源分配图需要识别每个受保护的共享资源,以及指向其中某一资源的所有线程。可以采用这几个过程步骤:①识别所有可能阻塞的系统调用,因为每个受保护的共享资源总是有一些与访问它有关的阻塞调用。②识别出获取共享资源的阻塞调用之后,在源代码中查找它们的各次调用情况。③对于每次调用,记录下指向资源的线程名称和该资源的名称。通常调用本身将受保护的资源作为一个参数来传递,通过这种方式可以识别出所有受保护的资源以及分配资源的线程。④建立资源分配图,并检查是否有任何资源存在循环路径。

  如果预先确定每一个共享资源并建立分配图是不实际或不可能的,此时可以增加一些额外的代码,以便在系统运行时检测出潜在的死锁。许多不同的算法都致力于优化这个检测过程,但本质上它们几乎都动态地建立某种资源分配图。只要有线程请求、分配或释放资源,分配图就会被修改和检测,从而能确定是否存在潜在死锁的循环路径。

  (3)利用内核跟踪程序工具检测死锁
  有一些工具可以用来帮助发现代码中的死锁。例如远程内核跟踪程序(Kernel Tracker),它可用于检测运行设备上的进程、线程和中断之间的交互作用关系,还可用于定位和检测死锁情况。因此,开发人员通过采用工具来对代码进行统计分析,可以识别引起竞争条件和死锁的许多原因。

  (4)检测并解除死锁
  检测到某个死锁之后,唯一的克服方法是强迫线程释放关键的资源。通常,这意味着中断正保持着所需资源的线程,对于某些应用,这种方法可能是无法接受的。另一个有用的解决方案是在运行时收集资源分配情况并进行事后分析处理,以确定在程序运行过程中是否有死锁情况发生。尽管这种方法并不能防止在运行时发生死锁,但它有助于在死锁出现后发现问题并进行修复。

  线程死锁解除通常有如下做法:①撤销处于死锁状态的进程并收回它们的资源。具体地说,选择占用资源多的进程作为撤销对象或者选择撤销代价最小的那个进程。如果撤销一个进程不足以解除死锁,则继续再选另一个撤销对象,直到解除死锁。②资源剥夺方法。即从死锁进程中选一个进程,剥夺它的资源但不撤销它。让这些资源分配给别的死锁进程。反复做这一工作直到死锁解除。由于进程未被撤销,解除死锁的代价比较小。③进程回退。即让一个或多个进程回退到足以解除死锁的地步。它比资源剥夺法温和,因为进程回退时是自愿释放资源而不是被剥夺资源,回退方法要求Windows CE.NET系统保持更多的有关进程运行的历史信息。
 

0
相关文章