技术开发 频道

WinCE多线程并发 同步安全不容忽视

  【IT168 专稿】Windows CE是微软公司推出的一个多任务的操作系统,WinCE实现多任务的方法是采用多线程和多进程机制。一般来说,每一种使用多线程、多进程的操作系统都或多或少的会存在着并发线程的安全问题。在上周我所负责的WinCE开发项目中就遇到了一点麻烦,我在程序开发中陷入了多线程的安全陷阱中,并为此一度束手无策。

  一般来说,多线程的安全性是有多种级别的,所以每个人谈论的线程安全级别其实并不相同。对于多线程并发的安全问题,有些人概念不清需求不明,结果是在代码中处处加锁,影响性能不说还特别容易莫名其妙的死锁,而另外有一些人则是对多线程并发敬而远之,结果是使系统的处理效率大大减弱。所以,在进行WinCE多线程编程时最重要的不是片面的应用多线程并发,而是要理解怎样才能保证多线程并发的安全性。本文分享我在WinCE开发中对多线程并发的同步安全问题的一些教训和经验总结。

  1.让我痛苦的多线程并发安全问题

  (1)线程资源被占用与并发假死

  WinCE系统支持多线程,这无疑是一件很好的事情。因为这能给系统带来更好的并发性能,但这同时也带来了另一个比较棘手的开发问题,那就是如何让多线程的资源应用是安全的,这在WinCE多线程并发编程中是非常重要的。例如,这次的开发项目中就让我饱受反复调试之苦。原因是经常出现多个线程对同一个资源进行并发操作,结果是出现资源被占用的状态报错,或者是系统出现并发假死使到效率低下而变慢。

  一般来说,多线程的并发安全性是指一个线程在被调用过程中,还未返回时又再次被其它线程调用,在这种情况下执行结果的可靠性。如果结果是可靠的,则称这个多线程并发安全的;如果结果是不可靠的,则称这个多线程并发是不安全的。不安全的原因是发生了线程资源被占用或并发冲突。因此,多线程并发安全性如果处理不当,轻则导致程序运行时出错或假死,严重的话将导致WinCE系统崩溃。

  (2)最常见的并发线程安全问题:死锁

  由于在调试过程中多次出现资源被占用的情况,而且跟踪资源是否被占用的过程是非常费心费力的。因此,在开发过程中我大量通过锁定一个资源来防止任何其它线程访问这个资源,以避免资源竞争。但没有想到的是,这又导致了多线程资源争夺的另一个常见问题:死锁。为了避免并发死锁,我只好逐一分析资源占用和死锁的过程,这个分析过程不但让我备受折磨和感到痛苦不堪,而且开发项目也一度陷入进退两难的困境之中。

  所谓并发死锁(Dead Lock)是指在WinCE编程中两个或两个以上的并发线程在执行过程中,如果每个线程持有某种资源而又都在等待别的线程释放它们现在保持着的资源,因占用资源而造成的一种互相等待的现象。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的线程就称为死锁线程。

  2. 多线程并发为什么会有安全性问题?

  (1)什么是多线程并发?

  在谈到多线程安全的时候,我们首先必须了解什么是多线程。WinCE是一个抢占多任务的操作系统,抢占多任务又称为调度,多线程是多任务的特殊形式。多线程是指允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。多线程的目的是为了使多个线程并行工作以完成多项任务,以此来提高系统的效率。

  从并发性的角度来看,不仅可以在不同的进程之间并发执行,而且在同一个进程中的多个线程也是可以并发执行的。一般来说,除了一些必不可少的资源外,线程本身并不占有系统的资源。但是线程却可以和同属于一个进程的另一个线程共享进程所拥有的全部资源,而且一个线程还可以创建或者撤销另一个线程,因此当处理不当时就会发生资源冲突问题了。

  (2)并发线程的优先级问题

  WinCE操作系统具有实时性,所以调度系统必须保证高优先级线程先运行,低优先级线程只有在高优先级线程终止后或者阻塞时才能得到CPU时间片。WinCE不像其它Windows操作系统将进程分为不同的优先级类,WinCE只将线程分为256个优先级。0优先级最高,255最低。0到248优先级属于实时性优先级,一般分配给实时性应用程序、驱动程序、系统程序。248到 255优先级一般分配给普通应用程序线程使用。

  每一个线程都有五种状态,分别为运行、挂起、睡眠、阻塞、终止。一旦发生中断,WinCE内核会暂停低优先级线程的运行,让高优先级线程继续运行,直到终止或者阻塞。具有相同优先级的线程平均占有CPU时间片,当一个线程使用完了 CPU时间片或在时间片内阻塞、睡眠,其它相同优先级的线程才会占有时间片。这里提到的CPU时间片是指内核限制线程占有CPU的时间,默认为100ms。在调度过程中,内核的调度系统包含一个当前所有进程中线程的优先级列表,并对所有的线程按优先级排列顺序。这个并发调度算法表面上看起来已经很有效、很完美了,但在实际的WinCE编程中,许多开发人员却会因为经验不足而经常发生资源被占用或资源死锁。

0
相关文章