我在Python 3中有一个多线程应用程序,并且有一个列表的setter和getter方法。 setter方法将一个元素附加到列表中,而getter方法在返回后删除列表中的所有元素。
setter方法如下所示,它位于更大的异步函数中:
while self.semaphor:
print("waiting...")
time.sleep(0.001)
self.semaphor=True
self.messages.append(msg)
print("appended data!")
虽然getter方法如下所示:
while self.semaphor:
time.sleep(0.001)
self.semaphor = True
l = self.messages
self.messages = []
self.semaphor = False
if len(l) == 0:
return None
else:
return l
然而,应用程序崩溃时没有任何错误消息(可能是由于命令行中的多线程输出而隐藏),紧接在最新状态之后"追加数据" - 所以我想知道代码片段是否是线程安全且正确的?
答案 0 :(得分:4)
您的代码不是线程安全的,因为您的self.semaphore
处理不是线程安全的。两个线程可以将self.semaphore
读作False
,然后才能将其设置为True
,因为线程切换可以在指令之间的任何位置进行。
你想要使用的是proper thread lock object(信号量是在这里使用的错误原语)。
创建实例时,设置self.messages_lock = threading.Lock()
属性,每当需要更改messages
列表时,请使用:
with self.messages_lock:
# locked block of code, guaranteed to be thread-safe.
或
try:
while not self.messages_lock.acquire(timeout=0.01):
print("waiting...")
# locked block of code, guaranteed to be thread-safe.
finally:
self.messages_lock.release()
如果你必须有一个线程打印出它正在等待锁定。