当列表在python中是线程安全的时,删除它们是否安全?

时间:2018-03-06 08:55:59

标签: python multithreading

我在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

然而,应用程序崩溃时没有任何错误消息(可能是由于命令行中的多线程输出而隐藏),紧接在最新状态之后"追加数据" - 所以我想知道代码片段是否是线程安全且正确的?

1 个答案:

答案 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()

如果你必须有一个线程打印出它正在等待锁定。