<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      多線程編程--5種方法實現線程同步

      1:用Interlocked系列函數實現線程同步;

      2:用CRITICAL_SECTION及其系列函數實現線程同步;

      3:用RTL_SRWLOCK及其系列函數實現線程同步;

      4:用事件內核對象實現線程同步;

      5:用信號量內核對象實現線程同步;

       

      1:用Interlocked系列函數實現線程同步實例如下:

      //旋轉鎖
      #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<10;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]);
          } 
      }

      InterlockedExchange確保以原子的方式操作數據。執行速度非常快,缺點是如果要同步的部分執行的時間比較長的話,while循環會一直輪詢操作,浪費CPU的時間,在單核CPU的系統中,可能會出現while一直暫用CPU導致其他線程不能修改ISOK的值,導致不能跳出while循環,出現死循環。還有就是線程的優先級問題也能導致問題。

      2:用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);//刪除關鍵段
      }

      CRITICAL_SECTION同樣是以原子的方式操作數據,也只有以原子的方式操作數據才能實現線程的同步,所有實現線程同步的方法,最核心的部分就是以原子的方式操作數據,CRITICAL_SECTION執行的速度非常快,其內部有一個事件內核對象,當出現資源爭奪的時候,才會出現初始化這個事件內核對象,由于CRITICAL_SECTION執行非常快可能不會出現資源爭奪,也就沒有必要創建這個事件內核對象,這個事件內核對象創建后,會將當前線程之外的線程掛起,并記錄這些線程需要這個資源,其他線程就不會浪費CPU的時間,而這些被掛起的線程將由用戶模式變成內核模式,當這些線程需要的資源可用時,系統會將其中一個線程喚醒。

      還有一點值得注意:如果要同步的代碼執行得很快,在出現爭奪資源的時候,系統把其他線程掛起,而當前線程又馬上執行完成了,系統又將掛起的線程喚醒,這個過程是非常浪費CPU的,也影響程序的性能,為了避免這種情況,可以結合旋轉鎖和CRITICAL_SECTION,先用旋轉鎖輪詢一定次數,還不能獲得資源,再將線程掛起,等待資源被釋放,系統再將線程喚醒,實現這一功能的就是方法

      InitializeCriticalSectionAndSpinCount(

         LPCRITICAL_SECTION lpCriticalSection,

         DWORD dwSpinCount//旋轉鎖輪詢的次數

      );

      除了初始化CRITICAL_SECTION用的是方法InitializeCriticalSectionAndSpinCount,而不是方法InitializeCriticalSection,其他的都是一樣的。

      3:用RTL_SRWLOCK及其系列函數實現線程同步實例如下:

      //讀寫鎖 
      #include <iostream> 
      using namespace std;  
      #include <process.h>
      #include <windows.h> 
      const int threadNum=10;
      HANDLE hThread[threadNum]; 
      RTL_SRWLOCK  lock;//構造一個CRITICAL_SECTION實例
      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]);
          } 
           
      }

      SRWLock的目的和關鍵段是一樣的,就是對資源的保護,不讓其他線程訪問。不同的是,它區分線程是讀線程還是寫線程。我們都是知道,一個資源可以同時被多個線程同時讀,就是不能同時讀,或是讀寫。也是是說寫必須是獨占的方式,而讀可以以共享的方式訪問,如果以共享的方式訪問肯定就比CRITICAL_SECTION性能好。

      4:用事件內核對象實現線程同步實例如下:

      //事件
      #include <iostream> 
      using namespace std;  
      #include <process.h>
      #include <windows.h> 
      const int threadNum=10;
      HANDLE hThread[threadNum];
      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);
      }

      用內核對象實現線程同步,一個函數是必須知道的,它就是WaitForSingleObject。

      DWORD WaitForSingleObject(

          HANDLE hHandle,//內核對象的句柄

          DWORD dwMilliseconds//等待時間

      );

      該函數會一直等待,直到被指定的內核對象被觸發為止,或是等待的時間結束返回。

      CreateEvent(

          LPSECURITY_ATTRIBUTES lpEventAttributes,//安全控制

          BOOL bManualReset,//true:手動重置事件,false:自動重置事件

          BOOL bInitialState,//true:有信號,false:無信號

          LPCWSTR lpName//事件名稱

      );

      bManualReset為true表示事件觸發了并一直處于觸發狀態,就像打開的門,打開之后就是一直開著,沒有自動關上;false:一打開放一個進去進關了,需要用SetEvent再次觸發事件。

      5:用信號量內核對象實現線程同步實例如下:

      //信號量
      #include <iostream> 
      using namespace std;  
      #include <process.h>
      #include <windows.h> 
      const int threadNum=10;
      HANDLE hThread[threadNum];
      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);
      }

      信號量內核對象用來對資源進行計數。創建信號量內核對象的方法如下:

      CreateSemaphore(

          LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,//安全控制

          LONG lInitialCount,//初始資源數量

          LONG lMaximumCount,//最大并發數量

          LPCWSTR lpName//號量的名稱

      );

      lMaximumCount表示最大并發數量,可以用來設置系統的最大并發數量,如果我們把他的值設為1,lInitialCount也設為1,就是只有一個資源,且每次只能一個線程訪問,這樣就可以實現線程同步。

      在實現線程同步時,建議用方法2和方法3,如不能解決你的需求,再用方法4,方法5,用內核對象實現的線程同步性能要差一些。

      多線程編程5中實現線程同步的方法介紹差多就到此了,大家可能還有一些疑問,可以看看我之前關于多線程基礎知識的一些介紹:

      Windows線程基礎

      Windows內核對象簡介

      Windows幾種線程同步方法介紹

      posted @ 2013-03-31 14:46  古文觀芷  閱讀(24517)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 精品无码国产一区二区三区av| 国产999久久高清免费观看 | 91亚洲国产成人久久精| 国产三级国产精品国产专区| 中文字幕日韩有码av| 亚洲在av极品无码天堂| 亚洲男女羞羞无遮挡久久丫| 风间由美性色一区二区三区 | 免费人成再在线观看视频| 色悠悠国产精品免费在线| 永久免费av网站可以直接看的| 同心县| 国产成人高清精品免费软件| 亚洲精品综合第一国产综合| 中文字幕永久精品国产| 蜜桃成熟色综合久久av| 久久无码高潮喷水| 国产精品久久久久鬼色| 日本偷拍自影像视频久久| 国产91丝袜在线播放动漫| 国产毛片精品av一区二区| 东方av四虎在线观看| 日日摸天天爽天天爽视频| 亚洲av成人一区二区| 重口SM一区二区三区视频| 新昌县| 日韩va中文字幕无码电影| 中文字幕乱码一区二区免费| 国产成人精品一区二区三区| 日韩精品中文字幕一线不卡| 中文字幕av无码免费一区| 屏边| 99精品国产兔费观看久久99| 精品国产午夜肉伦伦影院| 东方四虎av在线观看| 国产精品午夜福利导航导| 久久av无码精品人妻出轨| 性色av一区二区三区v视界影院| 另类 亚洲 图片 激情 欧美| 视频二区中文字幕在线| 一区二区三区久久精品国产|