zoukankan      html  css  js  c++  java
  • C++线程同步总结

      1 /*know it before
      2 //unsigned long _beginthreadex( void *security, unsigned stack_size, unsigned ( __stdcall *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr );
      3 //第1个参数:安全属性,NULL为默认安全属性 
      4 //第2个参数:指定线程堆栈的大小。如果为0,则线程堆栈大小和创建它的线程的相同。一般用0 
      5 //第3个参数:指定线程函数的地址,也就是线程调用执行的函数地址(用函数名称即可,函数名称就表示地址) 
      6 //第4个参数:传递给线程的参数的指针,可以通过传入对象的指针,在线程函数中再转化为对应类的指针 
      7 //第5个参数:线程初始状态,0:立即运行;CREATE_SUSPEND:suspended(悬挂) 
      8 //第6个参数:用于记录线程ID的地址
      9 //如果你的编程只调用 Win32 API/SDK ,就放心用 CreateThread;如果要用到
     10 //C++ 运行时间库,那么就要使用 _beginthreadex ,并且需要在编译环境中选择 Use MultiThread Lib/DLL
     11 //绝对不要调用系统自带的CreateThread函数创建新的线程,而应该使用_beginthreadex,除非你在线程中绝不使用需要tiddata结构的运行时库函数
     12 
     13 //WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);   
     14 //threadNum 句柄的数量 最大值为MAXIMUM_WAIT_OBJECTS(64) 
     15 //hThread 句柄数组的指针 HANDLE 类型可以为(Event,Mutex,Process,Thread,Semaphore )数组 
     16 //BOOL bWaitAll 等待的类型,如果为TRUE 则等待所有信号量有效在往下执行,FALSE 当有其中一个信号量有效时就向下执行  
     17 //DWORD dwMilliseconds 超时时间 超时后向执行。 如果为WSA_INFINITE 永不超时。如果没有信号量就会在这死等。
     18 
     19 //CloseHandle(hThread[i]);
     20 //只是关闭了一个线程句柄对象,表示我不再使用该句柄,即不对这个句柄对应的线程做任何干预了,放弃控制权。并没有结束线程。
     21 */
     22 
     23 //用Interlocked系列函数实现线程同步实例如下:
     24 //旋转锁 当然这种方法会浪费cpu时间,因为cpu要不断地执行InterlockedExchange()函数,单CPU不推荐这种方法。
     25 #include <iostream> 
     26 using namespace std;  
     27 #include <process.h>
     28 #include <windows.h> 
     29 const int threadNum=10;
     30 HANDLE hThread[threadNum];
     31 volatile unsigned int ISOK=0;
     32 unsigned int _stdcall Interlocked(PVOID threadId)
     33 { 
     34     while(InterlockedExchange(&ISOK,1)==1) ; 
     35     cout<<"线程:"<<*(int*)threadId<<"开始"<<endl; 
     36     Sleep(100);
     37     cout<<"线程:"<<*(int*)threadId<<"结束"<<endl; 
     38     InterlockedExchange(&ISOK,0);  
     39     return 0;
     40 }
     41 
     42 void InterlockedTest()
     43 {
     44     int threadId[threadNum];
     45     for(int i=0;i<threadNum;i++)
     46     {
     47         threadId[i]=i+1;
     48     }
     49     cout<<"1:用Interlocked系列函数实现线程同步"<<endl;
     50     for(int i=0;i<threadNum;i++){ 
     51         hThread[i]=(HANDLE)_beginthreadex(NULL, 0, Interlocked,threadId+i, 0, NULL); 
     52     }
     53     WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);   
     54     for(int i=0;i<threadNum;i++)
     55     {
     56         CloseHandle(hThread[i]);
     57     } 
     58 }
     59 
     60 //用CRITICAL_SECTION及其系列函数实现线程同步实例如下:
     61 //关键段 
     62 // #include <iostream> 
     63 // using namespace std;  
     64 // #include <process.h>
     65 // #include <windows.h> 
     66 // const int threadNum=10;
     67 // HANDLE hThread[threadNum]; 
     68 CRITICAL_SECTION g_cs;//构造一个CRITICAL_SECTION实例
     69 unsigned int _stdcall  CriticalSection(PVOID threadId)
     70 { 
     71     EnterCriticalSection(&g_cs);//进入关键段
     72     cout<<"线程:"<<*(int*)threadId<<"开始"<<endl; 
     73     Sleep(100);
     74     cout<<"线程:"<<*(int*)threadId<<"结束"<<endl; 
     75     LeaveCriticalSection(&g_cs);//进入关键段 
     76     return 0;
     77 }
     78 
     79 
     80 void CriticalSectionTest()
     81 {
     82     int threadId[threadNum];
     83     for(int i=0;i<threadNum;i++)
     84     {
     85         threadId[i]=i+1;
     86     }
     87     InitializeCriticalSection(&g_cs);//初始化g_cs的成员 
     88     cout<<"2:用CRITICAL_SECTION及其系列函数实现线程同步"<<endl;
     89     for(int i=0;i<10;i++){ 
     90         hThread[i]=(HANDLE)_beginthreadex(NULL, 0, CriticalSection,threadId+i, 0, NULL);  
     91     }
     92     WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);   
     93     for(int i=0;i<threadNum;i++)
     94     {
     95         CloseHandle(hThread[i]);
     96     } 
     97     DeleteCriticalSection(&g_cs);//删除关键段
     98 }
     99 
    100 /*
    101 SRWLock的目的和关键段是一样的,就是对资源的保护,不让其他线程访问。
    102 不同的是,它区分线程是读线程还是写线程。
    103 我们都是知道,一个资源可以同时被多个线程同时读,就是不能同时读,或是读写。
    104 也是是说写必须是独占的方式,而读可以以共享的方式访问,如果以共享的方式访问肯定就比CRITICAL_SECTION性能好。
    105 */
    106 //用RTL_SRWLOCK及其系列函数实现线程同步实例如下:
    107 //读写锁 
    108 RTL_SRWLOCK  lock;//构造一个RTL_SRWLOCK实例
    109 unsigned int _stdcall  SrwLock(PVOID threadId)
    110 { 
    111     AcquireSRWLockExclusive(&lock);//进入读写锁
    112     cout<<"线程:"<<*(int*)threadId<<"开始"<<endl; 
    113     Sleep(100);
    114     cout<<"线程:"<<*(int*)threadId<<"结束"<<endl; 
    115     ReleaseSRWLockExclusive(&lock);//进入读写锁
    116     return 0;
    117 }
    118 
    119 void SrwLockTest()
    120 {
    121     int threadId[threadNum];
    122     for(int i=0;i<threadNum;i++)
    123     {
    124         threadId[i]=i+1;
    125     }
    126     InitializeSRWLock(&lock);//初始化lock的成员 
    127     cout<<"3:用RTL_SRWLOCK及其系列函数实现线程同步"<<endl;
    128     for(int i=0;i<10;i++){ 
    129         hThread[i]=(HANDLE)_beginthreadex(NULL, 0, SrwLock,threadId+i, 0, NULL);  
    130     }
    131     WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);   
    132     for(int i=0;i<threadNum;i++)
    133     {
    134         CloseHandle(hThread[i]);
    135     } 
    136 
    137 }
    138 //用事件内核对象实现线程同步实例如下:
    139 //事件
    140 HANDLE event1; 
    141 
    142 unsigned int _stdcall  Event(PVOID threadId)
    143 {
    144     WaitForSingleObject(event1,INFINITE);
    145     int* p=(int*)threadId;
    146     cout<<"线程:"<<*p<<"开始"<<endl; 
    147     Sleep(100);
    148     cout<<"线程:"<<*p<<"结束"<<endl;  
    149     SetEvent(event1);
    150     return 1;
    151 }
    152 
    153 void EventTest()
    154 {
    155     int threadId[threadNum];
    156     for(int i=0;i<threadNum;i++)
    157     {
    158         threadId[i]=i+1;
    159     }
    160     event1=CreateEvent(NULL,false,true,NULL); 
    161     cout<<"4:用事件内核对象实现线程同步"<<endl;     
    162     for(int i=0;i<threadNum;i++)
    163     {
    164         hThread[i] =(HANDLE)_beginthreadex(NULL, 0, Event ,threadId+i, 0, NULL);  
    165     }
    166     WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);  
    167     for(int i=0;i<threadNum;i++)
    168     {
    169         CloseHandle(hThread[i]);
    170     } 
    171     CloseHandle(event1);
    172 }
    173 
    174 //用信号量内核对象实现线程同步实例如下:
    175 //信号量
    176 HANDLE semaphore; 
    177 unsigned int _stdcall  Semaphore(PVOID threadId)
    178 {
    179     WaitForSingleObject(semaphore, INFINITE);  
    180     cout<<"线程:"<<*(int*)threadId<<"开始"<<endl; 
    181     Sleep(100);
    182     cout<<"线程:"<<*(int*)threadId<<"结束"<<endl; 
    183     ReleaseSemaphore(semaphore,1,NULL); 
    184     return 0;
    185 }
    186 
    187 void SemaphoreTest()
    188 {
    189     int threadId[threadNum];
    190     for(int i=0;i<threadNum;i++)
    191     {
    192         threadId[i]=i+1;
    193     }
    194     semaphore=CreateSemaphore(NULL,1,1,NULL);
    195     cout<<"5:用信号量内核对象实现线程同步"<<endl;
    196     for(int i=0;i<10;i++){ 
    197         hThread[i]=(HANDLE)_beginthreadex(NULL, 0, Semaphore,threadId+i, 0, NULL);  
    198     }
    199     WaitForMultipleObjects(threadNum, hThread, TRUE, INFINITE);   
    200     for(int i=0;i<threadNum;i++)
    201     {
    202         CloseHandle(hThread[i]);
    203     }
    204     CloseHandle(semaphore);
    205 }
    206 void main()
    207 {
    208     InterlockedTest();
    209     CriticalSectionTest();
    210     SrwLockTest();
    211     EventTest();
    212     SemaphoreTest();
    213 }
  • 相关阅读:
    B-Tree索引的学习记录
    mysql NOW,CURRENT_TIMESTAMP,SYSDATE 之间的区别
    哈希索引
    MyISAM和InnoDB的区别
    负载均衡记录一
    哈希索引
    mysql ZEROFILL属性
    redis常用命令及使用场景
    js Function()构造函数
    书写闭包的时候需注意一下情况
  • 原文地址:https://www.cnblogs.com/etwd/p/4762327.html
Copyright © 2011-2022 走看看