マルチスレッドを用いたプログラミングでは複数のスレッドが
データを共有することになる。そのために競合状態を避けなくては
ならない。お互いのスレッドがアクセスし、競合状態の生じやすい
部分を危険区域と呼ぶ。危険区域に一つのスレッドのみが入るように
する問題を相互排除問題と呼ぶ。
排他制御のための命令
test_and_set
1:Li=c;
2;C=1;
使い方
1:int C=0;
2:
3:void Ti()
4:int Li;
5:for(;;){
6:
7:for(;;){
8:test_and_set(Li);/*つまりCに1がセットされていた場合はループ*/
9:if(Li==0)break;
10:}
11:/*Critical section*/
12:C=0;/*再び通過できなくする*/
15:}
16:}
exchange命令
1:temp=A;
2:A=B;
3:B=temp;
1:int C=0;
2:void Ti(){
3:int Li=1;
4:for(;;){
5:for(;;){
6:exchange(C,Li);/*Cが1の間通過できない*/
7:if(Li==0) break;
8:}
9:/*Critical section*/
14:exchange(C,Li);/**/
15:}
16:}
ロック
ハードウエア依存の機械語命令を用いてプログラムを書くことは
望ましくない。オペレーティングシステムではロックと呼ばれる
わかりやすい機構が提供されている。
1:Lock lock;
1:void Lock(Lock,lock);
2:void Unlock(Lock lock);
セマフォア
セマフォアを用いるとロックだけでは記述しにくい問題を簡単に
記述できる。
1:Semaphore S=1;
1:void Wait(Semaphore S);
2:void Singal(Semaphore S)
1:Wait(S)
2:if(S >0) then S:=S-1;
3:そうでなければ待機
1:Signal(S)
2:if 待機しているプロセスがあれば起こす
3:そうでなければ S:=S+1
生産者/消費者問題
int B[N];
int In_Ptr=0,Out_Ptr=0;
Semaphore Elements=0;
Semaphore Spaces=N;
void Produre(){
int data;
for(;;){
data=Produce();
wait(Spaces);
B[In_Ptr]=data;
In_Ptr=(In_Ptr+1)%N;
Signal(Elements);
}
}
void Consumer(){
int data;
for(;;){
wait(Elements);
data=B[Out_ptr];
Out_Ptr=(Out_Ptr+1)%N;
Signal(Elements);
Consume(data);
}
}
モニタ
先ほどのようなライブラリによる機能とは異なり、プログラミング言語
自体が提供する機能としてモニタがある。モニタはクラスと似ている
monitor sample{
int shared_variables;
void increment(){
shared_variables++:
}
void decrement(){
shared_variables--;
}
}
モニタ内の手続きは複数のスレッドで同時に呼ぶことができないように
自動的に排他制御される。
最終更新:2009年07月09日 23:03