Python中的线程安全';词典
我有一个班上有一本字典Python中的线程安全';词典,python,multithreading,dictionary,thread-safety,Python,Multithreading,Dictionary,Thread Safety,我有一个班上有一本字典 class OrderBook: orders = {'Restaurant1': None, 'Restaurant2': None, 'Restaurant3': None, 'Restaurant4': None} @staticmethod def addOrder(restaurant_name, orders): OrderBook.o
class OrderBook:
orders = {'Restaurant1': None,
'Restaurant2': None,
'Restaurant3': None,
'Restaurant4': None}
@staticmethod
def addOrder(restaurant_name, orders):
OrderBook.orders[restaurant_name] = orders
我正在运行4个线程(每个餐厅一个)来调用方法OrderBook.addOrder
。以下是每个线程运行的函数:
def addOrders(restaurant_name):
#creates orders
...
OrderBook.addOrder(restaurant_name, orders)
这是安全的,还是在调用
addOrder
之前必须使用锁?是的,内置类型本质上是线程安全的:
这简化了CPython实现,使对象模型(包括关键的内置类型,如dict)对并发访问隐式安全
Python的内置结构对于单个操作来说是线程安全的,但有时很难看到一条语句真正变成了多个操作
你的代码应该是安全的。请记住:这里的锁几乎不会增加任何开销,并且会让您安心
有更多细节。谷歌的风格指南建议不要依赖dict原子性 详情请参阅: 不要依赖内置类型的原子性 虽然Python的内置数据类型(如字典)似乎具有原子操作,但在某些情况下它们不是原子的(例如,如果
\uuuuu hash\uuuuu
或\uuuuuu eq\uuu
被实现为Python方法),它们的原子性不应受到依赖。您也不应该依赖于原子变量赋值(因为这反过来又依赖于字典)
使用队列
模块的队列数据类型作为线程之间通信数据的首选方式。否则,请使用线程模块及其锁定原语。了解如何正确使用条件变量,以便可以使用线程化.condition
而不是使用较低级别的锁
我同意这一点:CPython中已经有了GIL,所以使用锁对性能的影响可以忽略不计。更昂贵的是,当这些CPython实现细节有一天发生变化时,在复杂的代码库中花上数小时寻找bug。当使用python的内置dict时,set和get是原子的(因为 然而,这似乎是一种不好的做法,因为像.items这样的操作不是原子的
注意-如果多个线程在同一个dict键上工作,则get-add-set操作不是线程安全的。当每个线程都写入不同的键时,怎么会出现问题。@Jochen:根据dict的实现方式,可能会出现很多错误。这是一个非常合理的问题。这不是Python的特性,而是cpython的特性。没错,但据我所知,Jython和IronPython中的内置程序即使不使用GIL,也是线程安全的(如果出现unladen swallow,建议也取消GIL)。我假设他没有指定他正在使用的解释程序,他是用Cython来解释的。在Jython的情况下是正确的:这里是Effo.Org。为什么/HOTO to on应该考虑单个操作与复合操作,比如GET-AD-SET。问题是,当我经常读/写DICT时,这种心态的平静会花费我很多。“此处的锁几乎不会增加开销”:为什么?链接已断开,请参见此处: