转自http://blog.csdn.net/lwbeyond/article/details/7617234
Win32 中关于进程和线程的协调工作是由同步机制来完成的,同步机制相当于线程间的红绿灯。
一. 同步和异步
举个例子:
PostMessage(),是把消息放到对方的消息队列中,然后不管三七二十一,就回到原调用点继续执行,这就是异步。
SendMessage(),就像调用一般性函数,直到调用的函数结束,才会回到原点,这就是同步行为。
二. Critical Sections
如果一个线程已经进入某个临界区,则另一个线程就绝不能够进入同一个临界区。
- //初始化一个临界区
- VOID InitializeCriticalSection(
- LPCRITICAL_SECTION lpCriticalSection // critical section
- );
- //消除一个临界区
- VOID DeleteCriticalSection(
- LPCRITICAL_SECTION lpCriticalSection // critical section
- );
- //进入临界区
- VOID EnterCriticalSection(
- LPCRITICAL_SECTION lpCriticalSection // critical section
- );
- //离开临界区
- VOID LeaveCriticalSection(
- LPCRITICAL_SECTION lpCriticalSection // critical section
- );
- 例如:
- CRITICAL_SECTION gCriticalSection;
- void Function()
- {
- InitializeCriticalSection(&gCriticalSection);
- EnterCriticalSection(&gCriticalSection);
- //Do something here
- LeaveCriticalSection(&gCriticalSection);
- DeleteCriticalSection(&gCriticalSection);
- }
一旦线程进入一个临界区,则它就可以一再的重复进入该临界区,当然每个进入操作都必须对应离开操作。
也就是EnterCriticalSection( ),可以嵌套。
但是千万不要在临界区中调用 sleep(),或任何 Wait..() 函数。
临界区的缺点是:没有办法知道进入临界区中的那个线程是生是死。如果那个线程在进入临界区后当掉了,而且没有退出来,那么系统就没有办法消除掉此临界区。
三. Mutexes
Mutexes 用途和 Critical Section 非常类似,线程拥有 mutex 就好象线程进入 critical section 一样,但是它牺牲速度以增加弹性。
一旦没有任何线程拥有那个 mutex,这个 mutex 便处于激发状态
它与临界区的区别是:
1. Mutexes 操作要比 Critical Section 费时的多。
2. Mutexes 可以跨进程使用,Critical Section 则只能在同一进程中使用。
3. 等待一个 Mutex 时,你可以指定"结束等待"的时间长度,而 Critical Section 则不行。
- HANDLE CreateMutex(
- LPSECURITY_ATTRIBUTES lpMutexAttributes, // 安全属性,默认为NULL
- BOOL bInitialOwner, // initial owner
- LPCTSTR lpName // mutex 的名称,是一个字符串
- );
- //返回值:如果成功返回 handle,否则返回 NULL
- HANDLE OpenMutex(
- DWORD dwDesiredAccess, // access
- BOOL bInheritHandle, // inheritance option
- LPCTSTR lpName // object name
- );
- //打开一个已经存在的 mutex
- BOOL ReleaseMutex(
- HANDLE hMutex // handle to mutex
- );
- //调用过程如下:
- CreateMutex(); //创建
- WaitForXXXObject(); //等待
- ReleaseMutex(); //释放
- CloseHandle(); //关闭
说明:
1. Mutex 的拥有权:
Mutex 的拥有权并非属于那个产生它的线程,而是那个最后对些 Mutex 进行 WaitXXX() 操作并且尚未进行 ReleaseMutex() 操作的线程。
2. Mutex 被舍弃:
如果线程在结束前没有调用 ReleaseMutex(),比如线程调用了 EXitThread() 或者因为当掉而结束。这时的 mutex 不会被摧毁,而是被视为"未被拥有"以及"未被激发"的状态,在下一个 WaitXXX() 中线程会被以WAIT_ABANDONED_0 (WAIT_ABANDONED_0_n + 1 )来通知。
3. 最初拥有者:
CreateMutex(),第二个参数 bInitialOwner,允许你指定现行线程是否立刻拥有产生出来的 mutex。
如果没有指定立刻拥有的情况:
- HANDLE hMutex = CreateMutex(NULL, FALSE, "Sample Name");
- int result = WaitForSingleObject(hMutex, INFINITE);