Windows多线程编程时经常需要对多线程同时访问的公共数据进行互斥访问或者实现某个原子操作,有多个方法可以实现这个功能,最近了解了以下三种方法:
1. CRITICAL_SECTION cs;
初始化:InitialCriticalSection(&cs);
进入互斥区:EnterCriticalSection(&cs);
离开互斥区:LeaveCriticalSection(&cs);
最后释放:DeleteCriticalSection(&cs);
2. HANDLE hMutex;
初始化:hMutex = CreateMutex(NULL, FALSE, NULL);
进入互斥区:WaitForSingleObject(hMutex, INFINITE);
离开互斥区:ReleaseMutex(hMutex);
最后释放:CloseHandle(hMutex);
3. HANDLE hSemphore;
初始化:hSemphore = CreateSemphore(NULL, 1, 1, NULL);
进入互斥区:WaitForSingleObject(hSemphore, INFINITE);
离开互斥区:ReleaseSemphore(hSemphore, 1, NULL);
最后释放:CloseHandle(hSemphore);
以上三种方法都可以用在多线程的编程当中,而Mutex和Semphore还可以用在进程间的互斥访问中,Critical_Section只能用在单个进程当中,不过速度要更快。还有一个问题是需要特别注意的,就是Critical_Section和Mutex都是线程间互斥的,就是说如果你在一个线程当中进入互斥区多次都是不会阻塞的,只会在不同的线程进入时才会阻塞,而且在一个线程中进入了几次,就必须离开同样的次数,否则其它线程进入时也是会阻塞的。这看上去很少情况会发生,当是当你的程序在出错时忘记离开互斥区时,就可能会引起死锁,而当你只有一个线程时还会造成程序正常的假象,所以程序出错做异常处理时一定记得要离开互斥区。而使用Semphore则不会有只有不同线程才会阻塞的问题。