我正在考虑创建一个numpy表作为键/值数据库。 输入/更新将是多线程的。多头的Numpy插入
探索的想法, 问题:将GIL停止theads,只允许在一个时间更新。 问题:可以将numpy表(表空间)变为mutlitheaded。
我正在考虑创建一个numpy表作为键/值数据库。 输入/更新将是多线程的。多头的Numpy插入
探索的想法, 问题:将GIL停止theads,只允许在一个时间更新。 问题:可以将numpy表(表空间)变为mutlitheaded。
一些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见更多的选择和讨论。
我刚才已经需要的,所以我写了吧.. 去尝试,现在所以不知道是否可行尚未预期..
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,因为这仅仅是一个例子)。