windows多線程編程


 

進程共同實現某個任務或者共享計算機資源, 它們之間存在兩種關系:

1.同步關系, 指為了完成任務的進程之間, 因為需要在某些位置協調它們的執行順序而等待, 傳遞消息產生的制約關系.

2.互斥關系, 進程間因相互競爭使用獨占型資源所產生的制約關系, 如一個進程使用打印機,另一個進程必須等待它使用完后才可使用.

 

 

臨界資源: 一次僅允許一個進程使(必須互斥使用)的資源, 如獨占型硬件資源.....

臨界段: 指各進程必須互斥執行的程序段, 該程序段實施對臨界資源的操作.

 

關鍵區對象為:CRITICAL_SECTION 當某個線程進入關鍵區之后,其他線程將阻塞等待,直到該線程釋放關鍵區的擁有權.

 

#include <windows.h>
#include <stdio.h>
 
static int number=10;
CRITICAL_SECTION CriticalSection;
 
DWORD WINAPI ThreadOne(LPVOID lpParameter)
{
    printf("窗口1售票開始:\n");
    while(1)
    {
         EnterCriticalSection(&CriticalSection);  
         if(number>0)
         {
             printf("窗口1售出第%d張票...\n",number);
             number--;
             Sleep(1000);        
         }
         LeaveCriticalSection(&CriticalSection);
         Sleep(100);
    }
    return 0;
}
 DWORD WINAPI ThreadTwo(LPVOID lpParameter)
 {
     printf("窗口2售票開始:\n");
     while(1)
     {
         EnterCriticalSection(&CriticalSection);
         if(number>0)
         {
             printf("窗口2售出第%d張票...\n",number);
             Sleep(1000);
             number--;
         }
         LeaveCriticalSection(&CriticalSection);
         Sleep(100);
     }
     return 0;
 }
 
 
 int main()
 {
     HANDLE HOne,HTwo;
     InitializeCriticalSection(&CriticalSection);
     printf("***********************vpoet******************\n");
     HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);
     HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
     CloseHandle(HOne);
     CloseHandle(HTwo);
     while(TRUE)
     {
         if(number==0)
         {
             printf("不好意思,票賣完了!\n");
             DeleteCriticalSection(&CriticalSection);
             return 0;
         }
         else
         {
             continue;
         }    
     }
     
     return 0;
 }

 

 

信號量機制: 由信號量和P操作,V操作兩部分組成, 可以解決互斥與同步問題. 信號量(s)為一個整型變量, 只能被兩個標准原語訪問, 分別記為P操作和V操作.

定義如下:

 P(s){
     while s <= 0
         ; //空操作
          s = s - 1; 
 }
 
V(s){
    s =s + 1;
}

 

 

 信號量可以解決n個進程的臨界段問題, n個進程共享一個公共變量mutex, 其初值為 1 , 任意一個進程Pi的結果如下:

do{
    P(mutex);
    critical secition
    V(mutex);
    non critical secition
}while(1);

 

 

信號量也可以解決進程間同步問題.

 

利用信號量解決線程同步問題

 #include <windows.h>
 #include <stdio.h>
 
 static int number=10;
 HANDLE Sem;
 
 DWORD WINAPI ThreadOne(LPVOID lpParameter)
 {
     printf("窗口1售票開始:\n");
     while(1)
     {
          // 信號量 >  0, 減去 1 
         WaitForSingleObject(Sem,INFINITE);
         if(number>0)
         {
             printf("窗口1售出第%d張票...\n",number);
             number--;
             Sleep(1000);        
         }
         // 信號量  < 0 , 加上 1 
         ReleaseSemaphore(Sem,1,NULL);
         Sleep(100);
     }
     return 0;
 }
 DWORD WINAPI ThreadTwo(LPVOID lpParameter)
 {
     printf("窗口2售票開始:\n");
     while(1)
     {
         WaitForSingleObject(Sem,INFINITE);
         if(number>0)
         {
             printf("窗口2售出第%d張票...\n",number);
             Sleep(1000);
             number--;
         }
         ReleaseSemaphore(Sem,1,NULL);
         Sleep(100);
     }
     return 0;
 }
 
 
 int main()
 {
     HANDLE HOne,HTwo;
     
     printf("***********************vpoet******************\n");
     HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);
     HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
     //創建信號量, 初始為 1 , 最大計數為 1 
     Sem=CreateSemaphore(NULL,1,1,NULL);
     CloseHandle(HOne);
     CloseHandle(HTwo);
     while(TRUE)
     {
         if(number==0)
         {
             printf("不好意思,票賣完了!\n");
             CloseHandle(Sem);
             return 0;
         }
         else
         {
             continue;
         }    
     }
     
     return 0;
 }
 
 
View Code

 

 

信號量的具體實現:與進程調度相結合, 消除忙等待現象.

基本思想:

在P操作循環等待的地方介入放棄處理機, 進入等待對了動作.

在V操作時, 從等待隊列中摘取進程變為就緒.

 

信號量定義

typedef struct{
       int:value;  一個數值型變量
       struct process *L;一個PCB隊列
       } Semaphore
Semaphore S;

 

 P操作

   P(S):      S.Value=S.value-1;
              if S.value<0 then 保存現場,
              將本進程掛入S.L隊列,等待重新調度

請求分配一個S代表的資源, 若S.value < 0, 代表系統無此資源, 申請者阻塞. 

 

 

 V操作

   V(S):          S.value:=value+1
                  if S.value≤0 then 從S.L隊列
                  取一進程,掛入就緒隊列。

 進程釋放一個S代表的資源, 若S.value <= 0, 表示尚有進程在等待S而被阻塞, 所有要喚醒其一. 

 

 

管程

共享資源用共享數據結構表示, 把分散的對共享資源的臨界段集中於管程中, 管程中的臨界程序一次只允許一個進程調用.

主要構成:共享數據結構,  對共享數據結構操作的一組函數, 數據結構的初始化程序.

 

 

互斥對象實現線程同步

 

互斥對象的所有權輪換給兩個線程

 

#include <windows.h>
#include <stdio.h>

static int number=10;
HANDLE Mutex;

DWORD WINAPI ThreadOne(LPVOID lpParameter)
{
    while(1)
    {
        //等待互斥對象有多有權才返回 
        WaitForSingleObject(Mutex,INFINITE);  
        if(number>0)
        {
            printf("窗口1售出第%d張票...\n",number);
            number--;
            Sleep(1000);        
        }
        //釋放互斥對象所有權 
        ReleaseMutex(Mutex);    
    }
    return 0;
}
DWORD WINAPI ThreadTwo(LPVOID lpParameter)
{
    while(1)
    {
        WaitForSingleObject(Mutex,INFINITE);
        if(number>0)
        {
            printf("窗口2售出第%d張票...\n",number);
            Sleep(1000);
            number--;
        }
        ReleaseMutex(Mutex);
    }
    return 0;
}


int main()
{
    HANDLE HOne,HTwo;
    Mutex=CreateMutex(NULL,FALSE,NULL);
    printf("***********************vpoet******************\n");
    HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);
    printf("窗口1售票開始:\n");
    HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
    printf("窗口2售票開始:\n");
    CloseHandle(HOne);
    CloseHandle(HTwo);
    while(TRUE)
    {
        if(number==0)
        {
            printf("不好意思,票賣完了!\n");
            CloseHandle(Mutex);
            return 0;
        }
        else
        {
            continue;
        }    
    }

    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM