2011-12-28 57 views
1

我正在考虑创建一个numpy表作为键/值数据库。 输入/更新将是多线程的。多头的Numpy插入

探索的想法, 问题:将GIL停止theads,只允许在一个时间更新。 问题:可以将numpy表(表空间)变为mutlitheaded。

回答

4

一些numpy的功能不是原子,因此,如果两个线程是通过调用一些非原子numpy的功能的相同阵列上操作,则阵列将变得错位,因为操作的顺序将在一些非混淆预期的方式。

有很多的例子,只是要具体,numpy.apply_along_axis是Python语句的长序列,显然不是原子。

的GIL不会帮助你,因为它可以阻止一个线程,而这只是部分通过一些非原子numpy的功能,然后开始被在同一阵列上运行的另一个线程...

所以要线程安全的,你需要使用一个threading.Lock和锁已被收购后仅在阵列上运行:

with lock: 
    arr = ... 

有到处使用锁质疑是否有具有多线程运行的任何好处在同一阵列上。请注意,有时 多线程在CPU绑定问题may result in slower performance比可比较的单线程版本。

ParallelProgramming with numpy and scipy wiki page见更多的选择和讨论。

1

我刚才已经需要的,所以我写了吧.. 去尝试,现在所以不知道是否可行尚未预期..

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的数组类。然后我有一个控制类,因为后来我想让更多线程安全的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,因为这仅仅是一个例子)。