歡迎關(guān)注我的微信公眾號:「阿拉平平」
最近寫腳本時涉及到了多線程和生成器疏遏,在使用過程中遇到了數(shù)據(jù)競爭的問題,特此記錄下救军。
在執(zhí)行腳本時提示以下錯誤:
ValueError: generator already executing
多線程同時請求生成器數(shù)據(jù)(即同時調(diào)用next方法)就會引發(fā)該錯誤财异,所以只要在調(diào)用next方法時加個鎖就可以解決。
在腳本開頭處加入:
class threadsafe_iter:
"""Takes an iterator/generator and makes it thread-safe by
serializing call to the `next` method of given iterator/generator.
"""
def __init__(self, it):
self.it = it
self.lock = threading.Lock()
def __iter__(self):
return self
def __next__(self): # python3
with self.lock:
return self.it.__next__()
# def next(self): # python2
# with self.lock:
# return self.it.next()
def threadsafe_generator(f):
"""A decorator that takes a generator function and makes it thread-safe.
"""
def g(*a, **kw):
return threadsafe_iter(f(*a, **kw))
return g
說明:
- 由于next方法的不同唱遭,所以需要區(qū)別python環(huán)境戳寸。
- threadsafe_generator為裝飾器,使用時只需在生成器上加入
@threadsafe_generator
即可拷泽。 - 具體的例子可以參考:https://gist.github.com/platdrag/e755f3947552804c42633a99ffd325d4