2009-04-17 15 views
2
import time 
import threading 

class test(threading.Thread): 
    def __init__ (self): 
     threading.Thread.__init__(self) 
     self.doSkip = False 
     self.count = 0 

    def run(self): 
     while self.count<9: 
     self.work() 

    def skip(self): 
     self.doSkip = True 

    def work(self): 
     self.count+=1 
     time.sleep(1) 
     if(self.doSkip): 
     print "skipped" 
     self.doSkip = False 
     return 
     print self.count 

t = test() 
t.start() 
while t.count<9: 
    time.sleep(2) 
    t.skip() 

答えて

2

どのようにしてスレッドセーフですか?私はあなたがここで保護したいと思わない部分は見ません。

スキップすると、いつでもdoSkipがリセットされる可能性があります。したがって、ロックするにはあまり意味がありません。あなたは同時にアクセスされるリソースを持っていないので、このコードでIMHOは何も壊れたり危険になることはありません。

ロック/カウントによって異なって実行される部分は、.skip()へのすべての呼び出しで「スキップ」がいくつ行われるかだけです。すべてのスキップでスキップされた結果が.work()になるようにするには、doSkipを増分と比較/減分の両方のロックによって保護されているカウンタに変更する必要があります。現在、チェックの後でdoSkipがリセットされる前に、1つのスレッドがdoSkipをオンにする可能性があります。この例では重要ではありませんが、実際の状況では(コードを増やすことで)差が出る可能性があります。

0

明らかに重要なリソースはないので、スレッドセーフです。

しかし、通常どおり、2つのスレッドがスケジューラによってブロック/実行される順序を予測することはできません。

0

スレッド間でデータを共有しない限り、これはスレッドセーフです。

スレッドクラスにデータを読み書きする必要がある場合は、同期メカニズム(ロックなど)でデータを保護しない限りスレッドセーフではありません。

1

mutexブール値のテスト(たとえばif(self.doSkip))がmutexブール値のセットとは別の場合は、おそらくスレッドの問題が発生します。

最も不便な時間にスレッドがスワップアウトされるというルールがあります。つまり、テストの後、セットの前に。それらを互いに近づけて動かすことは、ネジアップの窓を減少させるが、それらを排除するものではない。ほとんどの場合、そのウィンドウを完全に閉じるために、言語またはカーネルから特別に作成されたメカニズムが必要です。

スレッディングライブラリには、スレッドの同期やコードのクリティカルセクションの作成に使用できるセマフォがあります。 DanMの答えについては詳しく説明し

0

は、おそらくこれが起こる可能性:

  1. スレッド1:t.skip()
  2. スレッド2:if self.doSkip: print 'skipped'
  3. スレッド1:t.skip()
  4. スレッド2:self.doSkip = False
  5. など。

つまり、t.skip()へのすべてのコールで1つの「スキップ」が発生することが予想されるかもしれませんが、この一連のイベントはそれに違反します。

しかし、sleep()コールのため、この一連のイベントは実際には不可能だと思います。

(コンピュータがゆっくり本当にを実行している場合を除く)

関連する問題