| 订阅 | 在线投稿
分享
 
 
 

WIN32下DELPHI中的多线程【同步2】(五)

2006-12-10 06:53:47  编辑来源:互联网  国际版  评论
 
 
  线程同步2

   上一文中曾经介绍了线程同步的一些方法,其实完成同步还有很多很多的办法,这里最后介绍一种方式--信号量内核对象。并借此来回顾线程同步。

   在谈论信号量之前,我想先谈论另外一种方式,一种你最好不要使用的方式。假设你有一个公共内存区域,你不希望一个线程在完成一个操作之前另外一个线程对他进行另外的操作。抛开前面所有的知识,我们可以使用这样一种办法,一种所有人都会想到的办法。

   程序中设置一个布尔类型的公共变量FLAG,此公共变量唯一的最用是决定线程是否是否可以操作公共内存区域。如果是TRUE则允许操作,如果是FALSE则禁止操作。在线程将要执行对共享内存的操作时,反复判断此变量,类似一个死循环,直到FLAG变为TRUE。思路很简单,实现起来也比前面介绍的那些方法更容易,在某种意义上说,它也是有效的。但文章前面曾经说过,最好不用使用这种方式,为什么?回顾线程的工作状态,我们基本可以这样划分,

  1、处于可调度状态(挂起),此状态下的线程正在等待CPU分配时间片给它来执行自己的操作

  2、等待状态,此时的线程我们可以称它处在不可调度状态,CPU绝不会在等待事件未发生之前分配时间片给它,例如一个线程正在等待某件事情的发生,就比如前边说的等待事件内核对象的状态变为已通知

  3、CPU已分配时间片给线程,它正在执行自己的操作。

   假如我们使用事件内核对象来完成一些线程的同步,那么前面曾经说过,当等待函数检测到事件内核对象的状态为未通知状态时,此线程将处于等待状态,此时线程不会使用CPU,而如果使用前面介绍的那种反复判断变量的方法,那么此线程将占用CPU资源,这很重要,我始终认为,对于一个合格的程序员而言,绝对不要无谓的浪费客户的CPU资源。

   虽然我说上面那种循环判断公共状态位的办法不可取,但它却反映了线程同步的思想,即使我们调用那些用于同步的API函数,事实上,同步的思想也是如此,只是实现的方法不同而已。

  信号量

   信号量内核对象用于对资源进行计数。它们与所有内核对象一样,包含一个使用数量,但是它们也包含另外两个带符号的32位值,一个是最大资源数量,一个是当前资源数量。最大资源数量用于标识信标能够控制的资源的最大数量,而当前资源数量则用于标识当前可以使用的资源的数量。

   信号量的使用规则如下:

   &bull