2011-12-28 12 views

答えて

4

2つのスレッドがいくつかの非アトミックnumpyの関数を呼び出すことにより、同じアレイ上で動作した場合の動作の順序は、いくつかの非中に混合されるので、その後、アレイは、マングルになるであろうように、いくつかのnumpyの機能は、アトミックではありません予想通り。

は多くの例があるが、ちょうど具体的には、numpy.apply_along_axisはPythonの文の長いシーケンスは明らかに、アトミックではありません。それは部分的にしかいくつかの非アトミックnumpyの機能により、同じアレイ上で動作している別のスレッドを起動している間、それは一つのスレッドを停止する可能性があるので

GILは

そうであることを...あなたを助けにはなりませんどこにでもロックを使用する必要が

with lock: 
    arr = ... 

が動作する複数のスレッドを持つことにどんな利点があるかどうかを疑問に呼び出します:スレッドセーフでは、あなたはthreading.Lockを使用して、ロックが取得された後にのみ、アレイ上で動作する必要があります同じアレイ上にある。 CPUバインドの問題で マルチスレッドが発生する場合があります。may result in slower performanceは、同等のシングルスレッドバージョンよりも多いことに注意してください。

は、より多くの選択肢と議論のためにもParallelProgramming with numpy and scipy wiki pageを参照してください。

1

私はちょうどので、私は...まだ期待通りに動作するかどうかそうかわからない、今それを試してnumpyの配列のためのクラスです

class LockedNumpyArray(object): 
    """ 
    Thread safe numpy array 
    """ 
    def __init__(self): 
     self.lock = threading.Lock() 
     self.val = None 

    def __get__(self, obj, objtype): 
     self.lock.acquire() 
     if self.val != None: 
      ret_val = self.val.copy() 
     else: 
      ret_val = None 
     self.lock.release() 
     # print('getting', ret_val) 
     return ret_val 

    def __set__(self, obj, val): 
     self.lock.acquire() 
     # print('setting', val) 
     self.val = val.copy() 
     self.lock.release() 

を行く.. それを書いたことを必要なまし。その後、私は制御のためのクラスを持っているので、後で私はスレッドセーフなnumpy配列を動作させたいからです。

class CaptureControl(): 
    """ 
    Shared class to control source capture execution 
    """ 
    frame = LockedNumpyArray() 

    def __init__(self): 
     print(self.frame) 
     self.frame = np.array([2]) 
     print(self.frame) 

最後に、このCaptureControlクラスのインスタンスを次のようにスレッドに入れました。

class CaptureThread(threading.Thread): 
    """ 
    Thread running source capturing 
    """ 
    def __init__(self, capture_control): 
     threading.Thread.__init__(self) 
     self.capture_control = capture_control 
     self.sleepTime = 0.01 
    def run(self): 
     while True: 
      self.capture_control.capture_frame() 
      time.sleep(self.sleepTime) 

if __name__ == '__main__': 
    capture_control = CaptureControl() 
    capture_thread = CaptureThread(capture_control) 
    capture_thread.start() 

誰でもスレッド実行機能でtime.sleep含めない、このソリューションについてどんな考えを共有している場合、これは単なる一例であると私は喜んでいるでしょう;)。

関連する問題