临界区,互斥,信号量

来源:互联网 发布:淘宝司法拍卖车辆 编辑:程序博客网 时间:2024/05/01 19:40

临界区(criticalSection) 临界区,互斥,信号量 - lijin_hz@126 - lijin_hz@126的博客临界区,互斥,信号量 - lijin_hz@126 - lijin_hz@126的博客
又称阻塞,它能够使一段代码只由一个线程来执行,其它线程被挡在这段代码之外,直到第一个线程执行完代码。临界区的使用主要涉及如下API函数:
initializeCriticalSection(), 在临界区首次使用之前,用此函数进行初始化。
deleteCreticalSection(), 在临界区不再使用之前,用此函数释放临界区。
enterCriticalSection(), 在初始化之后,用此函数进入阻塞。
leaveCriticalSection(), 在代码执行完之后,用此函数解除阻塞。

互斥(mutex)
互斥比较类似阻塞,关键在于互斥可以跨进程的线程同步,很多只允许应用程序运行一次的实例就是用互斥方法来实现的。互斥用到以下的API函数:
createMutex(), 创建互斥对象。
releaseMutex(), 解除互斥关系。

互斥的一般使用流程:
首先createMutex创建互斥对象,然后waitForSingleObject进入互斥环境,当用到同步的代码执行完成后,用releaseMutex解除互斥关系,当所有线程访问完后,调用
closeHandle方法释放互斥对象。

waitForSingleObject()函数来防止其它线程进入同步区域的代码。
function waitforsingleobject(hHandle: Thandle; dwMilliseconds: DWORD):   DWORD; stdcall;
这个函数可以使当前线程在dwmilliseconds指定的时间内睡眠,直到hHandle参数指定的对象进入发信号状态为止。一个互斥对象不再被线程拥有时,它就进入发信号状态
当一个进程要终止时,它就进入发信号状态。dwmilliseconds参数可以设为0,这意味着只检查hhandle参数指定的对象是否处理发信号状态,而后立即返回。dwmilliseconds参数设为INFINITE,表示如果信号不出现将一直等下去。

waitForSingeObject()使用的返回值及其含义:
WAIT ABANDONED
指定的对象是互斥对象,并且拥有这个互斥对象的线程在没有释放此对象之前就已终止。此时就称互斥对象被抛弃。这种情况下,这个互斥对象归当前线程所有,并把它设为不发信号状态。
WAIT OBJECT 0
指定的对象处于发信号状态
WAIT TIMEOUT
等待的时间已过,对象仍然是非发信号状态

当一个互斥对象不再被一个线程所拥有,它就处于发信号状态。此时首先调用waitForsingleobject()的线程就成为该互斥对象的拥有者,此互斥对象设为不发信号状态。当线程调用releaseMutex()并传递一个互斥对象的句柄作为参数时,这种拥有关系就被解除,互斥对象重新进入发信号状态。除waitforsingleobject()外,还可以使用waitformultipleobject()和msgwaitformultipleobject(),它们可以等待几个对象变为发信号状态。

信号量(semaphore)

另一种使线程同步的技术是使用信号量对象。它是在互斥的基础上建立的。但信号量增加了资源计数的功能,预定数目的线程允许同时进入要同步的代码。用createSemaphore()来创建一个信号量对象,其声明如下:

function createsemaphore(lpSemaphoreAttributes: pSecurityAttributes;
lInitalCount, lMaximunCount: longint; lpName: pchar): Thandle; stdcall;
 

和createmutex()一样,createsemaphore()的第一个参数也是一个指向TsecurityAttributes记录的指针,此参数的缺少值可以设为nil。lInitialcount参数用来指定个信号量的初始计数值,这个值必须在0和lMaximumcount之间。此参数大于0,就表示信号量处于发信号状态。当调用waitforsingleobject()时,此计数值就减1。当调用releasesemaphore()时,此计数值加1。参数lMaximumcount指定计数值的最大值。如果这个信号量代表某种资源,那么这个值代表可用资源总数。参数lpName用于给出信号量对象的名称。类似于createmutex()的lpName参数。

releaseSemaphore()的声明:
function releaseSemaphore(hsemaphore: Thandle; lreleasecount: longint;
lppreviouscount: pointer): bool; stdcall;
 

ireleasecount参数用于指定每次使计数值加多少。如果参数lppreviouscount不为nil,原有的计数值将存储在lppreviouscount里。信号量对象并不属于某个线程。


       记住,最后一定要调用colsehandle()来释放由createsemaphore()创建的信号量对象的句柄。

 

线程同步技术。
   1. Critical Sections(临界段),源代码中如果有不能由两个或两个以上线程同时执行的部分,可以用临界段来使这部分的代码执行串行化。它只能在一个独立的进程或一个独立的应用程序中使用。使用方法如下:
   //在窗体创建中
   InitializeCriticalSection(Critical1)
   //在窗体销毁中
   DeleteCriticalSection(Critical1)
   //在线程中
   EnterCriticalSection(Critical1)
   ……保护的代码
   LeaveCriticalSection(Critical1)
   2. Mutex(互斥对象),是用于串行化访问资源的全局对象。我们首先设置互斥对象,然后访问资源,最后释放互斥对象。在设置互斥对象时,如果另一个线程(或进程)试图设置相同的互斥对象,该线程将会停下来,直到前一个线程(或进程)释放该互斥对象为止。注意它可以由不同应用程序共享。使用方法如下:
   //在窗体创建中
   hMutex:=CreateMutex(nil,false,nil)
   //在窗体销毁中
   CloseHandle(hMutex)
   //在线程中
   WaitForSingleObject(hMutex,INFINITE)
   ……保护的代码
   ReleaseMutex(hMutex)
   3. Semaphore(信号量),它与互斥对象相似,但它可以计数。例如可以允许一个给定资源同时同时被三个线程访问。其实Mutex就是最大计数为一的Semaphore。使用方法如下:
   //在窗体创建中
   hSemaphore:= CreateSemaphore(nil,lInitialCount,lMaximumCount,lpName)
   //在窗体销毁中
   CloseHandle(hSemaphore)
   //在线程中
   WaitForSingleObject(hSemaphore,INFINITE)
   ……保护的代码

原创粉丝点击