臨界段——win32 API函數

一、有關函數:

   InitializeCriticalSection()    創建一個臨界段

   DeleteCriticalSection()        釋放一個臨界段

   EnterCriticalSection()         獲取對臨界段的所有權,獨佔共享資源

   TryEnterCriticalSection()      試圖獲得對臨界段的所有權,但不阻塞

   LeaveCriticalSection()         釋放對資源的所有權

 

二、舉例

1,

#include<windows.h>
#include<process.h>
#include<stdio.h>
CRITICAL_SECTION cs;
int a[5];
void Thread(void* pParams)
{
 int i,num=0;
 while(1)
 {
  EnterCriticalSection(&cs);//試圖獲得臨界段對象
  for(i=0;i<5;i++)
  a[i]=num;
  num++;
  LeaveCriticalSection(&cs);//釋放對臨界段對象的所有權
 }
}
int main(void)
{
 InitializeCriticalSection(&cs);//初始化臨界段對象
 _beginthread(Thread,0,NULL);
 while(1)
 {
  EnterCriticalSection(&cs);
  printf("%d %d %d %d %d/n",a[0],a[1],a[2],a[3],a[4]);
  LeaveCriticalSection(&cs);
 }
 return 0;
}

以上黑色部分是沒利用臨界段的,可想而知,結果是無法預知的。加了紅色部分之後,就可以有規律的輸出了,因爲賦值和輸出的順序得到了妥善安排,而不會亂佔亂用。

臨界段,就猶如領導,若沒得到領導的允許,就不允許行動;若領導禁止了,就必須停止行動。

 

2、關於銀行中客戶獲取ID 問題

#include<windows.h>
#include<process.h>
#include<iostream.h>
CRITICAL_SECTION cs;
unsigned int currentID=1;

unsigned long _stdcall MyThread(LPVOID pParam)
{
 int id;
 EnterCriticalSection(&cs);
 id = currentID;
 Sleep(0);//將本時間片的NGCHU剩餘時間讓出。爲了把不同步效果明顯表現出來,現實中不用Sleep
 currentID++;
 LeaveCriticalSection(&cs);
 cout<<"My Idntifier is:"<<id<<endl;
 return id;
}
int main(int argc,char *argv[])
{
 HANDLE handle;
 DWORD dw;//保存新線程的id
 InitializeCriticalSection(&cs);
 for(int i=0;i<100;i++)
 {
  handle = CreateThread(NULL,0,MyThread,NULL,0,&dw);
  CloseHandle(handle);
 }
 Sleep(6000);
 return 0;
}

以上,若沒有加上紅色部分,輸出會十分混亂,導致很多人都擁有了相同的ID號。加上了之後,就能夠有條不紊的按照獲得的ID號進行輸出。

 

三、比較:

第一個例子是創建了一個線程,然後讓其自行運行,只要把輸入輸出按順序就行。

第二個例子是按照每次需要,每次都創建線程,可以人工控制輸入輸出,然後也依然是按順序來。

另外:

我們發現上面用了兩個不一樣的創建線程的函數:_beginthread 和 CreateThread

1、_beginthread是c++的函數 ,CreateThread是windows API函數

2、_beginthread只是簡單的去執行線程,而CreateThread是通過句柄去執行線程,執行結束要要記得關閉句柄


發佈了82 篇原創文章 · 獲贊 22 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章