一、原子互锁家族函数:
(1)InterlockedIncrement: 加1操作。
(2)InterlockedDecrement: 减1操作。
(3)InterlockedExchangeAdd: 加上“指定”的值,可以加上一个负数。
(4)InterlockedExchange、InterlockedExchangePointer: 能够以原子操作的方式用第二个的值来代替第一个参数的值。
特点:一般情况下,在多线程编程中如果对某一个变量的值进行改变的话,使用以上互锁函数确实比较方便,但有时候多线程操作更为复杂的东西,比如对于给结构体赋值、对链表插入或者删除等等,以上互锁函数不能满足。
二、Critical Sections(关键代码段、关键区域、临界区域)
(1)初始化:InitializeCriticalSection(&csObj);
(2)删除:DeleteCriticalSection(&csObj);
(3)进入:EnterCriticalSection(&csObj);
(4)尝试进入:TryEnterCriticalSection(&csObj);
(5)离开:LeaveCriticalSection(&csObj);
特点:(1)是一个用户模式的对象,不是系统核心对象,所以执行速度快有效率。
(2)因为不是核心对象,所以不能跨进程使用。
(3)可以多次“进入”,但必须多次“推出”。
(4)最好不要同时进入或等待Critical Sections,容易造成死锁。
(5)无法检测到进入到Critical Sections里面的线程当前是否已经退出。
三、Mutex(互斥器)
(1)创建互斥器:HANDLE ghMutex = CreateMutex(NULL, FALSE, FALSE);
(2)打开一个已经存在的互斥器:OpenMutex;
(3)获取互斥器的拥有权: DWORD dwWaitResult = WaitForSingleObject(ghMutex, INFINITE);
(4)释放互斥器的拥有权:ReleaseMutex(ghMutex);
(5)关闭互斥器:CloseHandle(ghMutex);
DWORD dwWaitResult = WaitForSingleObject(ghMutex, INFINITE); switch (dwWaitResult) { case WAIT_ABANDONED: case WAIT_OBJECT_0: num++; ReleaseMutex(ghMutex); default: break; }
注意:Mutex可以跨进程使用,所以器名称对整个系统而言是全局的,所以不要命名不要过于普通。
特点:
(1)是一个系统核心对象,所以又安全描述指针,用完了要CloseHandle关闭句柄,这些是内核对象的共同特征:
(2)因为是核心对象,所以执行速度会比Critical Sections慢几乎100倍的时间。
(3)因为是核心对象,可以跨进程使用。
(4)Mutex使用正确的情况下不会发生死锁。
(5)在“等待”一个Mutex的时候,可以指定“结束等待”的时间长度。
(6)可以检测到当前拥有互斥器所有权的线程是否已经退出,Wait...函数返回:WAIT_ABANDONED。
四、Semaphores(信号量)
(1)创建一个信号量:hgSemaphore = CreateSemaphore(NULL, 10, 10, NULL);
(2)获取互斥器的拥有权:DWORD dwWaitResult = WaitForSingleObject(hgSemaphore, 0);
(3)释放互斥器的拥有权:ReleaseSemaphore(hgSemaphore,1,NULL);
(4)关闭互斥器:CloseHandle(hgSemaphore);;
while (true) { DWORD dwWaitResult = WaitForSingleObject(hgSemaphore, 0); switch (dwWaitResult) { case WAIT_OBJECT_0: CString csText; csText.Format(_T("ThreadId:%d "), GetCurrentThreadId()); OutputDebugString(csText); ReleaseSemaphore(hgSemaphore,1,NULL); case WAIT_TIMEOUT: CString csText; csText.Format(_T("wait time out! "), GetCurrentThreadId()); OutputDebugString(csText); } }
特点:
(1)是一个系统核心对象,所以又安全描述指针,用完了要CloseHandle关闭句柄,这些是内核对象的共同特征:
(2)因为是核心对象,所以执行速度会比较慢。
(3)因为是核心对象,可以跨进程使用。
(4)Semaphores使用正确的情况下不会发生死锁。
(5)在“等待”一个Semaphores的时候,可以指定“结束等待”的时间长度。
(6)非排他性的占有,跟Critical Sections和Mutex不同,这两种而言是排他性占有,即:同一时间只能又单一线程操作对象,而Semaphores同一时间内可以有多个线程获得目标并操作。