私は現在、クリティカルセクションとセマフォについて学んでおり、この部分で行き詰まっています。皆さんが私に洞察を与えてくれることを願っています。
私はこれらの3つのタイプのスレッドを持っています:1つはスタックでpop()を実行し、もう1つは同じスタックでpush()を実行し、最後のスレッドはそのスタックの値を出力します。現時点では、クリティカルセクションとして想定したものにwait()とsignal()を配置しました。
class Example{
public static void main(){
//create thread objects
StackPop p1 = new StackPop();
StackPop p2 = new StackPop();
StackPop p3 = new StackPop();
StackPush ps1 = new StackPush();
StackPush ps2 = new StackPush();
StackPush ps3 = new StackPush();
StackValues s1 = new StackValues();
StackValues s2 = new StackValues();
StackValues s3 = new StackValues();
//then we start these threads in mix orders
p1.start();
s3.start();
ps2.start();
// etc
}
}
class StackPop extends Thread{
public void run(){
mutex.wait();
pop();
SOP("value popped is " + get.popVal);
mutex.signal();
}
}
class StackPush extends Thread{
public void run(){
mutex.wait();
push();
SOP("value inserted is " + get.pushVal);
mutex.signal();
}
}
class StackValues extends Thread{
public void run(){
mutex.wait();
for(int i = 0; i<stack.size(); i++)
S.O.P.("["+getVal(i)+"]"); //where getVal() will retrieve value at that index
mutex.signal();
}
}
上記のコードは簡略化されたバージョンですが、考え方は同じです。私の問題は、wait()とsignal()を使用したにもかかわらず、非常に奇妙な出力が得られることです。たとえば、出力の一部に「挿入された[1][2][3]の値は3[5][@] [@]」と表示されます(@は内部に数字がないことを意味します)。これは、forループが値を取得している間に、プロセッサが別のスレッドを実行させているためだと思います。wait()とsignal()によって自動的にアトミックになると思っていましたが、何かを見逃した可能性があります。