线程之间的同步使用一些核心对象:如thread, process, evnet, mutex, semaphore. 在线程之间使用等待函数如WaitForSingleObjects, WaitForMultipleObjects. 等待函数使用核心对象的handle作为参数,如果handle被激发,则执行下一步。 handle被激发的条件: (handle是一段内存指针,为了掩藏内部实现而作的一个类型转化指针) 激发:---我的理解是资源未被战胜。 未激发: ---资源正在被占用。 eg: 1)thread, process被终止,则激发。 2)event: 要通过它的API来手动激发,是最灵活的激发方式,可被所有线程使用。 3)mutex: 没被任何线程所拥有,则激发。
1)临界区: CRITICAL_SECTION 适用范围: 单一进程的各线程之间用来排它性占有 特性: 局部性对象; 快速而有效. 无法监测是否被线程放弃 函数: EnterCriticalSection LeaveCriticalSection
2)Mutex: 适用范围: 不同线程之间用来排它性占有 特性: 核心对象, 可以使用wait进行等待,只能被拥有线程所释放 函数:CreateMutex ReleaseMutex
3)semaphore: 信号量 适用范围: 用来限制资源占用 特性: 核心对象,没有拥有者,任何线程都可释放 函数:CreateSemaphore OpenSemaphore ReleaseSemaphore
4)Event: 适用范围: 同来控制对象信号的接收,常与信号系统结合起来 特性: 核心对象 函数: CreateEvent OpenEvent PulseEvent SetEvent ResetEvent 5)Interlocked 简单的原子操作,如写文件中对文件中字节范围的锁定_locking
NOTE: 线程同步中很重要的可归纳为锁系统lock和信号系统signal lock包括:CRITICAL_SECTION, Mutex, wait function: WaitForMultipleObjects WaitForSingleObject Sleep 6)completion port 适用范围: 网络异步接收,包括文件读写 特性:由OS来控制读写, 是windows平台最有效的同步机制,相当于linux的AIO或者非阻塞socket+epoll 函数: CreateIoCompletionPort GetQueuedCompletionStatus
示例1: event //事件机制: 设置一个全局event对象,这个只能等待最多64个对象,而且要用WaitForMultipleObjects来监视线
程handle数组. 不如完全端口completion port HANDLE ghWriteEvent; HANDLE ghThreads[THREADCOUNT]; //(1)创建个手动事件,一开始不接受任何信号no signel //ResetEvent: 用来信号重置,同CreateEvent or OpenEvent ghWriteEvent = CreateEvent( NULL, // default security attributes TRUE, // manual-reset event FALSE, // initial state is nonsignaled TEXT("WriteEvent") // object name ); //(2)产生一堆线程,设置事件响应信号signal, if (! SetEvent(ghWriteEvent) ) { printf("SetEvent failed (%d)/n", GetLastError()); return; } //(3)设置线程等待事件,所有线程都接到这个事件,,这里对线程进行了同步,只有所有线程都执行了,才执行下一步 dwWaitResult = WaitForMultipleObjects( THREADCOUNT, // number of handles in array ghThreads, // array of thread handles TRUE, // wait until all are signaled INFINITE); { //(3.1)其中每个线程函数都在等待事件对象,这里也对线程进行了同步,只有得到signal的线程才执行下一步 dwWaitResult = WaitForSingleObject( ghWriteEvent, // event handle INFINITE); // indefinite wait
} //(4)关闭了这个全局事件 == CloseHandle(ghWriteEvent) CloseEvents();
示例2: completion port (1) 创建完成端口, 与一个监听socket发生关联 CreateIoCompletionPort (2) 产生一堆线程,让线程在完全端口循环等待. CreateThread--(WorkerThread)--
GetQueuedCompletionStatus (3) 接收监听socket的读写请求accept,将accept socket与完全端口关联,....?
参考资料: http://msdn2.microsoft.com/en-us/library/ms686360(VS.85).aspx