標籤:span 硬體 訊號量 eth mutex ica nbsp for word
進程共同實現某個任務或者共用電腦資源, 它們之間存在兩種關係:
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隊列 } SemaphoreSemaphore 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而被阻塞, 所有要喚醒其一.
管程
共用資源用共用資料結構表示, 把分散的對共用資源的臨界段集中於管程中, 管程中的臨界程式一次只允許一個進程調用.
主要構成:共用資料結構, 對共用資料結構操作的一組函數, 資料結構的初始化程式.
windows多線程編程