- Critical Sections(临界区):用来实现“排他性占用”。适用范围是单一进程的各线程之间。
- 一个局部对象,不是一个核心对象
- 快速而有效率
- 不能同时有一个以上的Critical Section被等待
- 无法侦测是否已被某个线程放弃
- 例子:
#include <windows.h> #include <process.h> #include <stdio.h> CRITICAL_SECTION cs; int a[ 5 ]; void Thread( void* pParams ) { int i, num = 0; while ( TRUE ) { EnterCriticalSection( &cs ); for ( i = 0; i < 5; i++ ) a[ i ] = num; LeaveCriticalSection( &cs ); num++; } } int main( void ) { InitializeCriticalSection( &cs ); _beginthread( Thread, 0, NULL ); while( TRUE ) { EnterCriticalSection( &cs ); printf( "%d %d %d %d %d\n", a[ 0 ], a[ 1 ], a[ 2 ], a[ 3 ], a[ 4 ] ); LeaveCriticalSection( &cs ); } return 0; }
- Mutexes(互斥器):是一个核心对象,可以在不同的线程之间实现“排他性占用”,甚至即使那些线程分属不同进程
- 一个核心对象
- 如果拥有mutex的那个线程结束,则会产生一个“abandoned”错误信息
- 可以使用Wait...()等待一个mutex
- 可以指定名称,因此可以被其他进程开启
- 只能被拥有它的那个线程释放
- 例子:
#include <windows.h> #include <process.h> #include <stdio.h> HANDLE hMutex; int a[ 5 ]; void Thread( void* pParams ) { int i, num = 0; while ( TRUE ) { WaitForSingleObject( hMutex, INFINITE ); for ( i = 0; i < 5; i++ ) a[ i ] = num; ReleaseMutex( hMutex ); num++; } } int main( void ) { hMutex = CreateMutex( NULL, FALSE, NULL ); _beginthread( Thread, 0, NULL ); while( TRUE ) { WaitForSingleObject( hMutex, INFINITE ); printf( "%d %d %d %d %d\n", a[ 0 ], a[ 1 ], a[ 2 ], a[ 3 ], a[ 4 ] ); ReleaseMutex( hMutex ); } return 0; }
- Semaphores(信号量):被用来追踪有限的资源
- 一个核心对象
- 没有拥有者
- 可以指定名称,因此可以被其他进程开启
- 可被任一线程释放
- 例子:
- Event Objects(事件):通常适用于overlapped I/O,或用来设计某些自定义的同步对象
- 一个核心对象
- 完全在程序掌控之下
- 适用于设计新的同步对象
- “要求苏醒”的请求不会被储存起来,可能会遗失掉
- 可以指定名称,因此可以被其他进程开启
- 例子:
#include <windows.h> #include <process.h> #include <stdio.h> HANDLE hEvent1, hEvent2; int a[ 5 ]; void Thread( void* pParams ) { int i, num = 0; while ( TRUE ) { WaitForSingleObject( hEvent2, INFINITE ); for ( i = 0; i < 5; i++ ) a[ i ] = num; SetEvent( hEvent1 ); num++; } } int main( void ) { hEvent1 = CreateEvent( NULL, FALSE, TRUE, NULL ); hEvent2 = CreateEvent( NULL, FALSE, FALSE, NULL ); _beginthread( Thread, 0, NULL ); while( TRUE ) { WaitForSingleObject( hEvent1, INFINITE ); printf( "%d %d %d %d %d\n", a[ 0 ], a[ 1 ], a[ 2 ], a[ 3 ], a[ 4 ] ); SetEvent( hEvent2 ); } return 0; }
- 参考:
- 《Win32多线程程序设计》
- http://www.codeproject.com/KB/threads/sync.aspx