C++线程同步总结
2015-08-27 09:29
417 查看
/*know it before //unsigned long _beginthreadex( void *security, unsigned stack_size, unsigned ( __stdcall *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr ); //第1个参数:安全属性,NULL为默认安全属性 //第2个参数:指定线程堆栈的大小。如果为0,则线程堆栈大小和创建它的线程的相同。一般用0 //第3个参数:指定线程函数的地址,也就是线程调用执行的函数地址(用函数名称即可,函数名称就表示地址) //第4个参数:传递给线程的参数的指针,可以通过传入对象的指针,在线程函数中再转化为对应类的指针 //第5个参数:线程初始状态,0:立即运行;CREATE_SUSPEND:suspended(悬挂) //第6个参数:用于记录线程ID的地址 //如果你的编程只调用 Win32 API/SDK ,就放心用 CreateThread;如果要用到 //C++ 运行时间库,那么就要使用 _beginthreadex ,并且需要在编译环境中选择 Use MultiThread Lib/DLL //绝对不要调用系统自带的CreateThread函数创建新的线程,而应该使用_beginthreadex,除非你在线程中绝不使用需要tiddata结构的运行时库函数 //WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE); //threadNum 句柄的数量 最大值为MAXIMUM_WAIT_OBJECTS(64) //hThread 句柄数组的指针 HANDLE 类型可以为(Event,Mutex,Process,Thread,Semaphore )数组 //BOOL bWaitAll 等待的类型,如果为TRUE 则等待所有信号量有效在往下执行,FALSE 当有其中一个信号量有效时就向下执行 //DWORD dwMilliseconds 超时时间 超时后向执行。 如果为WSA_INFINITE 永不超时。如果没有信号量就会在这死等。 //CloseHandle(hThread[i]); //只是关闭了一个线程句柄对象,表示我不再使用该句柄,即不对这个句柄对应的线程做任何干预了,放弃控制权。并没有结束线程。 */ //用Interlocked系列函数实现线程同步实例如下: //旋转锁 当然这种方法会浪费cpu时间,因为cpu要不断地执行InterlockedExchange()函数,单CPU不推荐这种方法。 #include <iostream> using namespace std; #include <process.h> #include <windows.h> const int threadNum=10; HANDLE hThread[threadNum]; volatile unsigned int ISOK=0; unsigned int _stdcall Interlocked(PVOID threadId) { while(InterlockedExchange(&ISOK,1)==1) ; cout<<"线程:"<<*(int*)threadId<<"开始"<<endl; Sleep(100); cout<<"线程:"<<*(int*)threadId<<"结束"<<endl; InterlockedExchange(&ISOK,0); return 0; } void InterlockedTest() { int threadId[threadNum]; for(int i=0;i<threadNum;i++) { threadId[i]=i+1; } cout<<"1:用Interlocked系列函数实现线程同步"<<endl; for(int i=0;i<threadNum;i++){ hThread[i]=(HANDLE)_beginthreadex(NULL, 0, Interlocked,threadId+i, 0, NULL); } WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE); for(int i=0;i<threadNum;i++) { CloseHandle(hThread[i]); } } //用CRITICAL_SECTION及其系列函数实现线程同步实例如下: //关键段 // #include <iostream> // using namespace std; // #include <process.h> // #include <windows.h> // const int threadNum=10; // HANDLE hThread[threadNum]; CRITICAL_SECTION g_cs;//构造一个CRITICAL_SECTION实例 unsigned int _stdcall CriticalSection(PVOID threadId) { EnterCriticalSection(&g_cs);//进入关键段 cout<<"线程:"<<*(int*)threadId<<"开始"<<endl; Sleep(100); cout<<"线程:"<<*(int*)threadId<<"结束"<<endl; LeaveCriticalSection(&g_cs);//进入关键段 return 0; } void CriticalSectionTest() { int threadId[threadNum]; for(int i=0;i<threadNum;i++) { threadId[i]=i+1; } InitializeCriticalSection(&g_cs);//初始化g_cs的成员 cout<<"2:用CRITICAL_SECTION及其系列函数实现线程同步"<<endl; for(int i=0;i<10;i++){ hThread[i]=(HANDLE)_beginthreadex(NULL, 0, CriticalSection,threadId+i, 0, NULL); } WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE); for(int i=0;i<threadNum;i++) { CloseHandle(hThread[i]); } DeleteCriticalSection(&g_cs);//删除关键段 } /* SRWLock的目的和关键段是一样的,就是对资源的保护,不让其他线程访问。 不同的是,它区分线程是读线程还是写线程。 我们都是知道,一个资源可以同时被多个线程同时读,就是不能同时读,或是读写。 也是是说写必须是独占的方式,而读可以以共享的方式访问,如果以共享的方式访问肯定就比CRITICAL_SECTION性能好。 */ //用RTL_SRWLOCK及其系列函数实现线程同步实例如下: //读写锁 RTL_SRWLOCK lock;//构造一个RTL_SRWLOCK实例 unsigned int _stdcall SrwLock(PVOID threadId) { AcquireSRWLockExclusive(&lock);//进入读写锁 cout<<"线程:"<<*(int*)threadId<<"开始"<<endl; Sleep(100); cout<<"线程:"<<*(int*)threadId<<"结束"<<endl; ReleaseSRWLockExclusive(&lock);//进入读写锁 return 0; } void SrwLockTest() { int threadId[threadNum]; for(int i=0;i<threadNum;i++) { threadId[i]=i+1; } InitializeSRWLock(&lock);//初始化lock的成员 cout<<"3:用RTL_SRWLOCK及其系列函数实现线程同步"<<endl; for(int i=0;i<10;i++){ hThread[i]=(HANDLE)_beginthreadex(NULL, 0, SrwLock,threadId+i, 0, NULL); } WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE); for(int i=0;i<threadNum;i++) { CloseHandle(hThread[i]); } } //用事件内核对象实现线程同步实例如下: //事件 HANDLE event1; unsigned int _stdcall Event(PVOID threadId) { WaitForSingleObject(event1,INFINITE); int* p=(int*)threadId; cout<<"线程:"<<*p<<"开始"<<endl; Sleep(100); cout<<"线程:"<<*p<<"结束"<<endl; SetEvent(event1); return 1; } void EventTest() { int threadId[threadNum]; for(int i=0;i<threadNum;i++) { threadId[i]=i+1; } event1=CreateEvent(NULL,false,true,NULL); cout<<"4:用事件内核对象实现线程同步"<<endl; for(int i=0;i<threadNum;i++) { hThread[i] =(HANDLE)_beginthreadex(NULL, 0, Event ,threadId+i, 0, NULL); } WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE); for(int i=0;i<threadNum;i++) { CloseHandle(hThread[i]); } CloseHandle(event1); } //用信号量内核对象实现线程同步实例如下: //信号量 HANDLE semaphore; unsigned int _stdcall Semaphore(PVOID threadId) { WaitForSingleObject(semaphore, INFINITE); cout<<"线程:"<<*(int*)threadId<<"开始"<<endl; Sleep(100); cout<<"线程:"<<*(int*)threadId<<"结束"<<endl; ReleaseSemaphore(semaphore,1,NULL); return 0; } void SemaphoreTest() { int threadId[threadNum]; for(int i=0;i<threadNum;i++) { threadId[i]=i+1; } semaphore=CreateSemaphore(NULL,1,1,NULL); cout<<"5:用信号量内核对象实现线程同步"<<endl; for(int i=0;i<10;i++){ hThread[i]=(HANDLE)_beginthreadex(NULL, 0, Semaphore,threadId+i, 0, NULL); } WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE); for(int i=0;i<threadNum;i++) { CloseHandle(hThread[i]); } CloseHandle(semaphore); } void main() { InterlockedTest(); CriticalSectionTest(); SrwLockTest(); EventTest(); SemaphoreTest(); }
相关文章推荐
- C语言中将日期和时间以字符串格式输出的方法
- c++中的static关键字
- CDHtmlDialog的基本使用(C++调用JS函数的实现)
- C++标准转换运算符const_cast
- 关于C++、PHP和Swoole
- test
- C语言流输入和输出函数
- C++ Primer : 第十二章 : 动态内存之allocator类
- C++ Primer : 第十二章 : 动态内存之动态数组
- 最优化程序c++的方法
- C语言的特点
- 十二之再续:快速排序算法之所有版本的c/c++实现
- OC语言 关于description的探讨
- C++ 虚函数表解析
- OC语言 关于description的探讨
- 《Effective C++》Item2:尽量以const,enum,inline替换#define
- 浅谈C++中指针和引用的区别
- 浅析C++中的this指针
- [C/C++]使用boost时无法连接到正确的库,提示fatal error LNK1104
- 设计模式在游戏中的应用--建造者模式(九)