Python字典需要同步吗?
如果a有一个Python字典,并且有多个线程添加到其中,我必须这样做吗Python字典需要同步吗?,python,dictionary,synchronization,thread-safety,Python,Dictionary,Synchronization,Thread Safety,如果a有一个Python字典,并且有多个线程添加到其中,我必须这样做吗 如果我知道每个线程都将添加到自己的密钥中,则同步添加元素。(我的意思是,不能同时添加同一密钥)。如果每个线程的密钥不唯一,则可能需要同步对字典对象的访问。访问不一定是线程安全的 您始终可以使用来验证任何python代码;python线程上下文可以在任何操作码之间切换(操作码本身是原子执行的);可以通过几个操作码访问dict: >>> def foo(): ... somedict = {} ...
如果我知道每个线程都将添加到自己的密钥中,则同步添加元素。(我的意思是,不能同时添加同一密钥)。如果每个线程的密钥不唯一,则可能需要同步对字典对象的访问。访问不一定是线程安全的 您始终可以使用来验证任何python代码;python线程上下文可以在任何操作码之间切换(操作码本身是原子执行的);可以通过几个操作码访问dict:
>>> def foo():
... somedict = {}
... somedict['bar'] = 'spam'
...
>>> import dis
>>> dis.dis(foo)
2 0 BUILD_MAP 0
3 STORE_FAST 0 (somedict)
3 6 LOAD_CONST 1 ('spam')
9 LOAD_FAST 0 (somedict)
12 LOAD_CONST 2 ('bar')
15 STORE_SUBSCR
16 LOAD_CONST 0 (None)
19 RETURN_VALUE
有4个操作码与somedict['bar']=spam
行相关,加载somedict
引用,加载'bar'
和'spam'
常量,并调用存储操作。线程上下文可以在这些操作码之间切换
也就是说,如果保证每个线程的密钥都是唯一的,那么就可以不锁定结构;与所有操作码一样,STORE\u SUBSCR
操作码是由GIL下的python解释器执行的,因此多个线程存储在自己的密钥中并从中读取信息应该是安全的
Python标准库在几个位置执行此操作;使用
thread.thread_ident()
作为字典键,在字典中存储每个线程的信息。例如,在线程标识符上设置一个\u活动的
模块全局字典键。当每个线程的键不唯一时,您可能需要同步对字典对象的访问。访问不一定是线程安全的
您始终可以使用来验证任何python代码;python线程上下文可以在任何操作码之间切换(操作码本身是原子执行的);可以通过几个操作码访问dict:
>>> def foo():
... somedict = {}
... somedict['bar'] = 'spam'
...
>>> import dis
>>> dis.dis(foo)
2 0 BUILD_MAP 0
3 STORE_FAST 0 (somedict)
3 6 LOAD_CONST 1 ('spam')
9 LOAD_FAST 0 (somedict)
12 LOAD_CONST 2 ('bar')
15 STORE_SUBSCR
16 LOAD_CONST 0 (None)
19 RETURN_VALUE
有4个操作码与somedict['bar']=spam
行相关,加载somedict
引用,加载'bar'
和'spam'
常量,并调用存储操作。线程上下文可以在这些操作码之间切换
也就是说,如果保证每个线程的密钥都是唯一的,那么就可以不锁定结构;与所有操作码一样,STORE\u SUBSCR
操作码是由GIL下的python解释器执行的,因此多个线程存储在自己的密钥中并从中读取信息应该是安全的
Python标准库在几个位置执行此操作;使用
thread.thread_ident()
作为字典键,在字典中存储每个线程的信息。例如,将\u激活
模块全局字典键入线程标识符。可能的重复我不认为它是重复的。你是对的。但它是@shx2的复制品:它只是相似而已。在中,字典结构是静态的(线程中没有添加新的键),因此访问通常是安全的(最后,只更新一个指针引用)。这里,dict的结构改变了可能的dup,我不认为它是重复的,你是对的。但它是@shx2的复制品:它只是相似而已。在中,字典结构是静态的(线程中没有添加新的键),因此访问通常是安全的(最后,只更新一个指针引用)。这里,dict的结构改变了STORE\u SUBSCR
操作码不一定是原子的:如果覆盖一个已经存在的键,并且被覆盖的键或值使用\uu del\uu
(或者最后一次引用了这样做的东西),那么在释放对象时,您可以得到一个线程开关。在实践中,这不太可能是一个问题,但当您试图利用GIL避免显式锁定时,值得记住。STORE\u SUBSCR
操作码不一定是原子的:如果覆盖已经存在的键,并且被覆盖的键或值使用\u del\u
(或者最后一次引用了它)当对象被释放时,你可以得到一个线程开关。实际上,这不太可能是一个问题,但是当你试图利用GIL来避免显式锁定时,值得记住。