多线程同步可以解决如下两个问题:
[1] 使用多线程的时候,经常需要访问\修改同一个内存数据或共享的系统资源,当同一个内存数据被不同的线程同时修改时,便会产生冲突,程序出现中断。此时,使用多线程中临界区、互斥便可以解决这个问题。
[2] 内存数据的访问具有约束条件。例如将一份文件装入内存然后打印;设事件A表示文件装入内存,事件B表示打印文件,操作系统会把两个任务当做互不相关的线程去执行,此时必须要等到事件A发生才能执行事件B。因此使用多线程同步的事件机制,通过通知操作的方式保持线程的同步,便可以解决这个问题。
(1) 临界区Critical Section:
临界区是一种最直接的线程同步方式,保证同一时刻只有一个线程对共享资源进行访问。当有多个线程试图同时访问临界区时,第一个线程进去临界区后,其他的线程将被挂起,并按照时间先后顺序进行排队,当第一个线程离开临界区后,其他的线程按照访问顺序依次对临界区进行访问。
临界区操作:
EnterCriticalSection():进入临界区;
LeaveCriticalSection():离开临界区。
注意,临界区只能用来同步同一进程的线程,而不可用来同步多个进程中的线程。如果要同步不同进程的线程,则使用互斥量(Mutex)。
(2) 事件(Event)
事件通过通知操作的方式来保存线程的同步,并且可以实现不同进程间的线程同步操作。
事件操作:
CreateEvent():创建一个信号量
OpenEvent(): 打开一个事件
SetEvent(): 回置事件
WaitForSingleObject(hHandle hHandle; dwMilliseconds DWORD): 等待一个事件;这个函数可以使当前线程在dwMilliseconds指定的时间内睡眠,直到hHandle参数指定的对象进入发信号状态为止。(当hHandle为一个线程的句柄时,hHandle不再被线程拥有时,它就进入发信号状态。当一个进程要终止时,它就进入发信号状态。此时首先调用WaitForSingleObject()函数的线程就成为该对象的拥有者,此对象设为不发信号状态。)
WaitForMultipleObjects():等待多个事件;
WaitForMultipleObjects 函数原型:
WaitForMultipleObjects(
IN DWORD nCount, //等待句柄数
IN CONST HANDLE *lpHandles,//指向句柄数组
IN BOOL bWaitAll,//是否完全等待标志
IN DWORD dwMilliseconds//等待时间
)
参数nCount指定了要等待的内核对象的数目,存放这些内核对象的数组由lpHandles来指向。fWaitAll对指定的这nCount个内核对象的两种等待方式进行了指定,为TRUE时当所有对象都被通知时函数才会返回,为FALSE则只要其中任何一个得到通知就可以返回。dwMilliseconds在这里的作用与在WaitForSingleObject()中的作用是完全一致的。如果等待超时,函数将返回WAIT_TIMEOUT。
代码下载:http://download.csdn.net/detail/xyyhlark/4567795