2016-04-19 9 views
0

現在、セマフォとスレッドを使用するオペレーティングシステムクラスの宿題に関する質問に取り組んでいます。非常に混乱し、ここに誰かが助けることができるかと思っていました。私はこれまで持っているコード:私のプログラムがデッドロック状態にならないようにするにはどうすればよいですか? (セマフォ)

01 travelToShop(); //puts thread to sleep between 1 and 1000 cycles 
02 s1.acquire();  //lock semaphore, keeps mutual exclusion so no other 
03 //thread writes to variable while another one is trying to do the same 
04 
05 if (numofcust==5){ //cant have more then 5 customers in a "shop" 
06 s2.acquire();  //lock the shop, wait until shop reopens 
07 } 
08 numofcust++;   //increases variable telling class how many in shop 
09 arriveAtShop();  //print statement saying ive arrived, if i arrived 
10 //im technically in shop 
11 
12 s1.release();  //done writing to numofcust 
13 sittingInShop(); //puts thread to sleep between 1 and 1000 cycles 
14 //simulating having coffee 
15 
16 s1.acquire();  //refer to last "s1.acquire()" 
17 numofcust--;  //simulating leaving the shop 
18 if (numofcust==0){ //if shop empty 
19 s2.release();  //open the shop 
20 } 
21 leaveShop(); 
22 s1.release(); //refer to last "s1.release()"  

私は問題を知っているが、一度店頭で5人の顧客があるライン6と12であり、顧客の残りの部分は、(6行目)を待たなければなりません。私が待たなければならないのは、最初にs1を保有している人は、別の顧客が残すために取得しなければならないセマフォを保持しているからです(そのスレッドがそのスレッドを解放するためにスレッドが待っているロックを解放することはできません誰かのためのロックが終了します

IVEはやってみました次:。

05 if (numofcust==5){ //cant have more then 5 customers in a "shop" 
06 s1.release(); //release the lock so others can write to numofcust and read 
07 s2.acquire();  //lock the shop, wait until shop reopens 
08 s1.acquire(); //reacquire the lock so i can write to numofcust again 
09 } 

をしかし、私は私は誰もロックせずにnumofcustに書き込むことはできません。相互排除を維持するにはどうすればよいの相互排他

を破りましたしかし、waitiから保持されているため、あるスレッドがnumofcustにロックを保持しているデッドロックを防ぐ店が開いているまでは?

EDIT:5人の顧客が店頭で存在する場合、店外のすべてのお客様は、彼らのすべてが去るまで待つ必要がありますが、5人の未満の顧客がある場合、彼らは喜ばとしてで行くことができ

+0

は、私はちょうど私の教授が何のためにそれを目覚めさせると言ったので、おそらくないような場合には、もう一度それを試していない場合、それは、その後、0秒間スリープし、それをウェイクアップし、その利用可能かどうかをチェックするために置かれ、何を言っていると思いますひどい。 –

+0

私はそれが与えられたセマフォークラスが何をしていると信じていますか?(待ちクラスがやっているのですか?) public void synchronized acquire(){ while(value <= 0){ wait(); } 値 - ; } –

+0

これまでのところ、私は彼にセマフォー、ブール値、整数が良いと言ったのを尋ねました。 –

答えて

1

ます2つのセマフォを必要としません。 Semaphoreオブジェクトは、可変数の許可を持つことができます。許可があれば何度もセマフォを取得できます。セマフォは、すべての許可が取得されたときにのみブロックされます。パーミットが解放されると、ブロックされたスレッドは、新たに解放されたパーミットを獲得することができます。

許可はスレッドによって所有されていません。どのスレッドも任意の数の許可を解放できます。これにより、許可証を発行する際に多くの柔軟性が得られます。

許可をどのように解除するかは、入力した人の最高透かしに基づいて変更する必要があります。最高透かしが5未満の場合、すぐに解放されます。最高水準点が5になると、最後の人が去るまで待ってからすべての許可を解除します。これは、ショップ内の人数をセマフォ許可とは別にカウントし、フラグが5に達するとフラグを設定することを意味します。カウントとフラグは、一度に1つのスレッドのみで更新およびチェックする必要があります。

+0

私は5の初期値を設定し、5つのスレッドはセマフォを獲得します、どうすれば他の誰もが5つを残すまで待ち​​ます。 教授は、店内に5人未満の人がいると、人々は来ることができると言いました。しかし、5人がいたら、皆は5人がすべて退室するまで待たなければなりません。 –

+0

私は十分に具体的ではありませんでした5人が同じで、そこにある一度お店が5店であり、すべて5がなくなっているだけまで、ときに、他の人が –

+0

に入ることができるようになりますロックする必要があり、私はお店が空になるまでブロックする方法を説明するために、答えを編集しました時間 –

0

@ MattChampionの回答は良いですが、問題を解決する方法が複数あることがよくあります。

これを解決するための別の方法あなたがSemaphoreクラスを使用することができなかった場合、BlockingQueueを使用することです:

は、プログラムの開始時にブロッキングキューにある5「トークン」を入れてください。トークンは任意のオブジェクトである可能性があります。 (例:Object token = new Object();)次に、店に入る前に、各顧客スレッドが待ち行列からトークンを取り出し、店を出た後にトークンを待ち行列に戻すことを確認する。

スレッドがキューが空のとき(5人の顧客が店内にいるとき)、トークンを取得しようとすると、トークンが使用可能になるまでブロックされます。

ブロッキングキューは、あるスレッドから別のスレッドにオブジェクトを渡すパイプラインだけでなく、多くの方法で使用できる強力な抽象化です。

+0

私はあなたのアイデアが好きで、どこに行くのか見ていますが、それでセマフォークラス宿題が間違っている、その入力に感謝 –

関連する問題