Windows下的同步机制
Windows下提供了多种内核对象实现线程、进程间的同步和互斥,常用的有:
关键节(Critical Section):关键节不是内核对象,在用户态实现了同一进程中线程的互斥。由于使用时不需要从用户态切换到核心态,所以速度很快,但其缺点是不能跨进程同步,同时不能指定阻塞时的等待时间,只能无限等待。
互斥体:(Mutex):互斥体实现了和关键节类似的互斥功能,但区别在于:互斥体是内核对象,可以实现跨进程互斥,但需要在用户态和核心态之间切换,速度比关键节慢得多,可以指定阻塞时的等待时间。
事件(Event):事件也是内核对象,具有“信号态”和“无信号态”两种状态。当某一线程等待一个事件时,如果事件为信号态,将继续执行,如果事件为无信号态,那么线程被阻塞。能够指定阻塞时的等待时间。
信号量(Semaphore):信号量是一个资源计数器,当某线程获取某信号量时,信号量计数首先减1,如果计数小于0,那么该线程被阻塞;当某信号量被释放时,信号量计数首先加1,如果计数大于或等与0,那么唤醒某被阻塞的线程并执行之。
例子1, 利用互斥体创建单实例程序
#define GLOBAL_MUTEX "Global\\MyprogramMutex"
int main(int argc, char** argv)
{
HANDLE hMutex = NULL;
hMutex = CreateMutex( NULL, TRUE, GLOBAL_MUTEX);
if(hMutex == NULL)
return 0;
.....
}
例子2 利用信号量实现生产值消费者
HANDLE g_EmptyTaskSemaphore;//设置信号量用。empty_Semaphore表示空的缓冲池的数量
HANDLE g_FullTaskSemaphore;//用full_Semaphore表示满的缓冲池的数量
unsigned __stdcall Consumer(PVOID pvParam)
{
while(1){
WaitForSingleObject(g_EmptyTaskSemaphore,-1);
....
ReleaseSemaphore(g_FullTaskSemaphore,1,NULL);
}
return 0;
}
unsigned __stdcall Producer(PVOID pvParam)
{
while(1){
WaitForSingleObject(g_FullTaskSemaphore,-1);
.....
ReleaseSemaphore(g_EmptyTaskSemaphore,1,NULL);
}
return 0;
}
int main()
{
HANDLE hThread[2];
g_EmptyTaskSemaphore=CreateSemaphore(NULL,
0,
SIZE_TASKPOOL,
NULL);//创建信号量empty_Semaphore
g_FullTaskSemaphore=CreateSemaphore(NULL,
SIZE_TASKPOOL,
SIZE_TASKPOOL,
NULL);//创建信号量full_Semaphore
hThread[0] = (HANDLE)_beginthreadex(NULL, 0, Producer, NULL, 0, NULL);
hThread[1] = (HANDLE)_beginthreadex(NULL, 0, Consumer,NULL, 0, NULL);
return 0;
}