CRITICAL_SECTION
临界区不是内核对象,不能跨进程使用。与内核对象相比,使用起来花费较小。不能设定timeout。
Mutex
内核对象,功能与临界区类似,通过制定创建时内核对象的名字,可跨进程使用。内核对象使用完需要调用CloseHandle释放。
CreateMutex(NULL, false, L"MutexTest"),创建时第二个参数可以指定是否被当前线程获得,一般设为false,表示没有被当前线程获得。
进入时调用WaitForSingleObject()获得Mutex,离开时调用ReleaseMutex()释放Mutex。
如果一个拥有Mutex的线程在返回之前没有调用ReleaseMutex(),那么这个Mutex就被舍弃了,但是其他使用WaitForSingleObject()等待这个Mutex的线程仍能返回,并得到一个WAIT_ABANDONED_0返回值。能够知道一个Mutex被舍弃是Mutex特有的。所以即使忘记ReleaseMutex()也不会死锁。
并且只有拥有Mutex的线程调用ReleaseMutex释放才有效。而Event和Semaphore的受信和计数加1可以由其它线程操作。
Event
内核对象,有受信与非受信两种状态。非受信时WaitForSingleObject()等待,直到受信。
CreateEvent(NULL, false, true, NULL),创建时第二个参数可指定是否为手动类型,第三个参数指定初始状态是否为受信。
一般同步时第二个参数为false,使用自动类型,WaitForSingleObject()后,状态为非受信,离开时SetEvent()为受信。
若为手动类型,WaitForSingleObject()后不会自动变成非受信状态,需要ResetEvent()为非受信。
手动类型适用于设定非受信阻塞所有线程,然后手动设为受信,所有线程同时执行。
Semaphore
内核对象,可以指定同时访问共享资源的线程数。
CreateSemaphore(NULL, 2, 5, NULL),第二个参数是信号量初始值,第三个参数是最大值。
只要信号量的值不为0,就是受信的。WaitForSingleObject()后,信号量的值减1,当减到0时,信号量状态为非受信,不再允许其它线程访问。
离开时ReleaseSemaphore(hSemaphore,1,NULL),第二个参数指定了信号量增加的值,值非0则受信。
CRITICAL_SECTION
#include <iostream>
#include <windows.h>
#include <process.h>
using namespace std;
//全局CRITICAL_SECTION
CRITICAL_SECTION cs;
//线程函数
void ThreadProc(void* )
{
//进入临界区
::EnterCriticalSection(&cs);
::Sleep(150);
cout<<::GetTickCount()<<endl;
//退出临界区
::LeaveCriticalSection(&cs);
::Sleep(1500);
}
int main()
{
//初始化CRITICAL_SECTION
::InitializeCriticalSection(&cs);
//启动10个线程
for(int i=0; i<10; ++i)
{
::Sleep(5);
::_beginthread(ThreadProc, 0, NULL);
}
while(!getchar())
{
}
//销毁CRITICAL_SECTION
::DeleteCriticalSection(&cs);
return 0;
}
Event
#include <iostream>
#include <windows.h>
#include <process.h>
using namespace std;
//创建全局Event
HANDLE hEvent = ::CreateEvent(NULL, false, true, NULL);
//线程函数,进入时等待Event受信,进入后Event非受信,退出时将Event设为受信
void ThreadProc(void* )
{
::WaitForSingleObject(hEvent, INFINITE);
::Sleep(150);
cout<<::GetTickCount()<<endl;
::SetEvent(hEvent);
::Sleep(1500);
}
int main()
{
//启动10个线程
for(int i=0; i<10; ++i)
{
::Sleep(5);
::_beginthread(ThreadProc, 0, NULL);
}
while(!getchar())
{
}
//销毁Event
::CloseHandle(hEvent);
return 0;
}
Semaphore
#include <iostream>
#include <windows.h>
#include <process.h>
using namespace std;
//创建全局Semaphore
HANDLE hSemaphore = ::CreateSemaphore(NULL, 2, 5, NULL);
//线程函数,进入时等待Semaphore受信,进入后Semaphore计数减一,退出时将Semaphore计数加一
void ThreadProc(void* )
{
::WaitForSingleObject(hSemaphore, INFINITE);
::Sleep(150);
cout<<::GetTickCount()<<endl;
::ReleaseSemaphore(hSemaphore,1,NULL);
::Sleep(1500);
}
int main()
{
//启动10个线程
for(int i=0; i<10; ++i)
{
::Sleep(5);
::_beginthread(ThreadProc, 0, NULL);
}
while(!getchar())
{
}
//销毁Semaphore
::CloseHandle(hSemaphore);
return 0;
}
Mutex
#include <iostream>
#include <windows.h>
#include <process.h>
using namespace std;
//创建全局mutex
HANDLE hMutex = ::CreateMutex(NULL, false, L"MutexTest");
//线程函数,进入时获得mutex,退出时释放mutex
void ThreadProc(void* )
{
::WaitForSingleObject(hMutex, INFINITE);
::Sleep(150);
cout<<::GetTickCount()<<endl;
::ReleaseMutex(hMutex);
::Sleep(1500);
}
int main()
{
//启动10个线程
for(int i=0; i<10; ++i)
{
::Sleep(5);
::_beginthread(ThreadProc, 0, NULL);
}
while(!getchar())
{
}
//销毁mutex
::CloseHandle(hMutex);
return 0;
}