关于数据结构是否线程安全,这是老生长谈的问题,大并发下,如果没有用好,直接会导致严重问题。
比如,网上就有两种声音,有人说python 的 list, set, dict 的数据结构是线程安全的,有人说,这些数据结构不是线程安全的,到底这些数据结构是否线程安全?答案是肯定的,其实可以从字节码的角度看。
使用dis 模块,能直接看到python 翻译的字节码。
from dis import dis
dis(compile('del d[k]', 'example', 'exec'))
d = {"a": 123, "b": 999}
def pop():
global d
del d["a"]
dis(pop)
输出是:
3 0 LOAD_GLOBAL 0 (d)
3 LOAD_CONST 1 ('a')
6 DELETE_SUBSCR
7 LOAD_CONST 0 (None)
10 RETURN_VALUE
解释是 ,申明全局变量d, 倒入常量 'a', 删除,返回。比较好理解,注意这里的删除是一条字节码指令,是否线程安全的关键是什么,就是操作的指令条数,如果操作是两条,就不行,就可能内核切换,导致数据异常。
比如,python 的自增就不是线程安全的,
0 LOAD_GLOBAL 0 (a)
3 LOAD_CONST 1 (1)
6 INPLACE_ADD
7 STORE_GLOBAL 0 (a)
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
python 的自增就是两个操作,先add 再store ,明显一旦发生上下文切换,就会导致store 的数据异常。这种操作和读写全局变量不线程安全的原因是一样的。
主要提供了个思路,从底层看,到底这个程序某个步骤能不能原子的执行。所以,那些数据结构是否线程安全,都不重要,需要确定的时候,dis 下就能直观看出来了。