使用訊號量解決兩個執行緒同步問題
阿新 • • 發佈:2019-01-07
1.同步問題
我們知道多道程式設計理念的提出,使得執行緒(程序)和執行緒(程序)之間可以併發執行,但是有一些特殊的情況,請看下面的例子:
(https://img-blog.csdn.net/20170126160159642?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzM2NTA5Nzg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
這就引發了同步問題。
2.解決思路
我們採用訊號量的方式解決該同步問題,即當執行緒B執行之前一直等待執行緒A發出的訊號,一旦接收到執行緒A的訊號,執行緒B掛入就緒佇列準備執行,否則執行緒B一直掛在對應訊號量的等待佇列。
3.程式碼模擬
我們建立兩個執行緒A和B,建立後使其掛起。然後設定訊號量value初始值為0。先Resume B並在其之前設定等待命令,再Resume A並在其之後設定發出訊號命令:
#include "stdafx.h"
#include"stdio.h"
#include "stdlib.h"
#include "windows.h"
void init(){
int i;
for(i=0;i<3;i++){
lock[i]=0;
number[i]=0;
}
}
void wait(int *value,HANDLE w){
(*value)--;
if((*value)<0){
SuspendThread(w);
}
}
void signal(int *value,HANDLE w){
(*value)++;
if((*value)<=0){
ResumeThread(w);
}
}
DWORD WINAPI AThread(LPVOID lpParameter){
printf("執行緒A正在執行\n");
return 0;
}
DWORD WINAPI BThread(LPVOID lpParameter){
printf("執行緒B正在執行\n" );
return 0;
}
int main(){
HANDLE A,B;
int S=0; //設定訊號量初始值
init();
B=CreateThread(NULL,NULL,BThread,0,CREATE_SUSPENDED,NULL);
A=CreateThread(NULL,NULL,AThread,0,CREATE_SUSPENDED,NULL);
wait(&S,B);
ResumeThread(B);
ResumeThread(A);
signal(&S,B);
system("pause");
return 0;
}
這樣即使cpu先排程Thread B,B也會因為未收到A的訊號,從而掛起。