MSDN的文章参考: 使用互斥对象
一开始没看懂是啥意思,后面研究之后发现,
重点在这段代码,
while (dwCount < 20) { dwWaitResult = WaitForSingleObject( ghMutex, // handle to mutex INFINITE); // no time-out interval switch (dwWaitResult) { // The thread got ownership of the mutex case WAIT_OBJECT_0: __try { // TODO: Write to the database printf("Thread %d writing to database... ", GetCurrentThreadId()); dwCount++; } __finally { // Release ownership of the mutex object if (!ReleaseMutex(ghMutex)) { // Handle error. } } break;
我们可以认为两个线程都在抢占资源,但是WaitForSingleObject利用互斥锁限制了它们,只有获得互斥锁的线程才能写入数据。一个线程在写完数据之后,释放互斥锁,另外一个线程拿到了互斥锁,写入数据,再释放互斥锁,依次往复。
利用这个,也很好的实现了线程同步。
拥有互斥锁的线程可以在重复的等待函数调用中指定相同的互斥锁,而不会阻止其执行。通常,您不会重复等待相同的互斥锁,但是这种机制可以防止线程在等待已拥有的互斥锁时使其自身死锁。但是,要释放其所有权,线程必须在互斥体每次等待时都调用 一次ReleaseMutex。
两个或多个进程可以调用 CreateMutex创建相同的命名互斥体。第一个进程实际上创建了互斥锁,具有足够访问权限的后续进程仅打开了现有互斥锁的句柄。这使多个进程可以获取同一个互斥锁的句柄,同时使用户不必承担确保首先启动创建进程的责任。使用此技术时,应将bInitialOwner标志设置为FALSE。否则,可能很难确定哪个进程具有初始所有权。
与创建互斥锁类似的是使用CreateEvent,它可以初始化事件对象的状态。 也可以通过SetEvent来赋予事件对象是有信号状态。
HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, //SECURITY_ATTRIBUTES结构指针,可为NULL BOOL bManualReset, // 手动/自动 // TRUE:表示手动,在WaitForSingleObject后必须手动调用ResetEvent清除信号 // FALSE:表示自动,在WaitForSingleObject后,系统自动清除事件信号 BOOL bInitialState, //初始状态,FALSE为无信号,TRUE为有信号 LPCTSTR lpName //事件的名称 );
(1)手动设置:这种对象只可能用程序手动设置,在需要该事件或者事件发生时,采用SetEvent及ResetEvent来进行设置。
(2)自动恢复:一旦事件发生并被处理后,自动恢复到没有事件状态,不需要再次设置。
参考: CreateEventA