Threads[ConditionVariable][Create] - 状態変数を作成する
使い方
Create()
|
説明
|
|
•
|
Create コマンドは新しい状態変数を作成します。識別子として正の整数を返します。
|
•
|
一度 Destroy コマンドで破棄された状態変数は必要とされません。
|
|
|
例
|
|
これは生産者 - 消費者 (Producer/Consume) パターンの例です。
生産者は物を生産します (ここでは大域テーブルのタブ内の整数で表します) 。消費者は物があればを消費し、結果をテーブルの最後に挿入します。
2 つの状態変数と 1 つのミューテックスを持ちます。1 つ目の状態変数 (cp) は生産者のスレッドとして使います。生産者スレッドは、仕事がいっぱいであれば生産者の状態変数は待機します。もう一つの状態変数 (cc) は消費者が使います。物がない場合、消費者スレッドは生産者が物を作るまで待機します。
ミューテックスは大域変数タブへのアクセスを制御するために使います。
>
|
Producer := proc( m, cp, cc, max, mindiff )
global tab, e;
local i,j,n;
Threads:-Mutex:-Lock( m );
j := 0;
tab[ "maxjob" ] := mindiff;
tab[ "curjob" ] := 1;
for j from 1 to mindiff
do
tab[ j ] := 2*j;
end do;
Threads:-ConditionVariable:-Signal( cp );
Threads:-Mutex:-Unlock( m );
n := false;
while ( e )
do
Threads:-Mutex:-Lock( m );
j := tab[ "maxjob" ];
if ( j - tab[ "curjob" ] > mindiff/2 ) then
n := true;
Threads:-ConditionVariable:-Wait( cp, m );
end if;
for i from j to tab[ "curjob" ] + mindiff
do
tab[ i ] := 2*i;
end do;
tab[ "maxjob" ] := tab[ "curjob" ] + mindiff;
if ( n ) then
Threads:-ConditionVariable:-Broadcast( cc );
n := false;
end if;
Threads:-Mutex:-Unlock( m );
end do;
end proc:
|
>
|
Consumer := proc( m, cp, cc, max )
global tab, e;
local n, i, j, num;
num := 0;
while ( num < max )
do
Threads:-Mutex:-Lock( m );
while ( tab[ "curjob" ] = tab[ "maxjob" ] )
do
Threads:-ConditionVariable:-Signal( cp );
Threads:-ConditionVariable:-Wait( cc, m );
end do;
n := tab[ "curjob" ];
j := tab[ n ];
tab[ "curjob" ] := n + 1;
Threads:-Mutex:-Unlock( m );
j := add( i, i=1..j );
num := num+1;
Threads:-Mutex:-Lock( m );
tab[ n ] := j;
Threads:-Mutex:-Unlock( m );
end do;
end proc:
|
>
|
tab := table( ):
m := Threads:-Mutex:-Create();
|
>
|
cc := Threads:-ConditionVariable:-Create();
|
>
|
cp := Threads:-ConditionVariable:-Create();
|
生産者スレッドをスタートします。生産者スレッドがスタートするまで cp は待機しています。
>
|
Threads:-Mutex:-Lock( m );
id1 := Threads:-Create( Producer( m, cp, cc, 31, 10 ) );
|
>
|
Threads:-ConditionVariable:-Wait( cp, m );
Threads:-Mutex:-Unlock( m );
|
消費者スレッドをスタートします。毎回 100 個の物を消費し、5 つのスレッドで行うので 500 個の物を消費します。
>
|
id2 := [ seq( Threads:-Create( Consumer( m, cp, cc, 100 ) ), i=1..5 ) ];
|
終わるまで消費者スレッドを待機します。
>
|
Threads:-Wait( op( id2 ) );
Threads:-Mutex:-Lock( m );
|
生産者スレッドを終了します。
>
|
e := false:
Threads:-ConditionVariable:-Signal( cp );
Threads:-Mutex:-Unlock( m );
Threads:-Wait( id1 );
|
仕事の数を調べます。
>
|
print( tab[ "curjob" ] );
|
仕事の結果を調べます。
>
|
print( add( i, i=1..2*233 ) );
|
|
|