Thi*_*ien 8 python iterator thread-safety python-2.7
因为有时它比围绕队列设计解决方案更实用,我想编写一个简单的包装器来使迭代器线程安全.到目前为止,我从这些 主题中获得了灵感,并提出了两个想法:
class LockedIterator(object):
def __init__(self, it):
self._lock = threading.Lock()
self._it = it.__iter__()
if hasattr(self._it, 'close'):
def close(self):
with self._lock:
self._it.close()
self.__setattr__('close', close)
def __iter__(self):
return self
def next(self):
with self._lock:
return self._it.next()
Run Code Online (Sandbox Code Playgroud)
我不喜欢的是,如果我必须指定所有可能的方法,它会变得有点冗长 - 好吧,我不能 - 比如发电机的特殊情况.此外,我可能有一些其他迭代器,甚至更具体的方法现在已隐藏.
class LockedIterator(object):
def __init__(self, it):
self._lock = threading.Lock()
self._it = it.__iter__()
def __getattr__(self, item):
attr = getattr(self._it, item)
if callable(attr):
def hooked(*args, **kwargs):
with self._lock:
return attr(*args, **kwargs)
setattr(self, item, hooked)
return hooked
Run Code Online (Sandbox Code Playgroud)
这更简洁,但它只能拦截调用,而不是直接的属性更改.(现在隐藏这些属性以防止出现问题.)更重要的是,它使得Python不再将我的对象识别为迭代器!
什么是使所有迭代器(甚至更好:所有对象)都能工作的最佳方法,而不会产生漏洞抽象?在没有必要时我不太担心锁定,但是如果你能想出一个解决这个问题的解决方案,那太好了!
首先,你知道GIL吗?尝试编写多线程Python通常比使用简单的单线程版本的运行时间更慢.
您第一次尝试访问迭代器线程安全似乎是非常合理的.您可以使用生成器使其更具可读性:
def locked_iter(it):
it = iter(it)
lock = threading.Lock()
while True:
try:
with lock:
value = next(it)
except StopIteration:
return
yield value
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5849 次 |
| 最近记录: |