list 是 Python 常用的几个基本数据类型之一.正常情况下我们会对 list 有增删改查的操作,显然易见不会有任何问题.那么如果我们试着在多线程下操作list 会有问题吗"htmlcode">
import threading import time # 随意设置 count 的值,值越大错误抛出的越快 count = 1000 l = [] def add(): for i in range(count): l.append(i) time.sleep(0.0001) def remove(): for i in range(count): l.remove(i) time.sleep(0.0001) t1 = threading.Thread(target=add) t2 = threading.Thread(target=remove) t1.start() t2.start() t1.join() t2.join() print(l)
有时候一次运行并不一定就会出错,多次重试之后会出现类似下面的错误
很显然这种操作方式不具有普适性,如果要是欧气太强,说不定会一直不出现异常。
那么出了这种方式,有没有比较简单有效的方法吗?答案是有的
dis
dis 库是 Python 自带的一个库,可以用来分析字节码。这里我们需要有这样的认识,字节码的每一行都是一个原子操作,多线程切换就是以原子操作为单位的,如果一个操作需要两行字节码就说明它是线程不安全的
remove
这里我们先看一下上面 list
的 remove
操作
> import dis > def test_remove(): ... a = [1] ... a.remove(0) ... > dis.dis(test_remove) 2 0 LOAD_CONST 1 (1) 2 BUILD_LIST 1 4 STORE_FAST 0 (a) 3 6 LOAD_FAST 0 (a) 8 LOAD_ATTR 0 (remove) 10 LOAD_CONST 2 (0) 12 CALL_FUNCTION 1 14 POP_TOP 16 LOAD_CONST 0 (None) 18 RETURN_VALUE
从上面不难看出,整个 remove
操作被分成了好几条指令,这就意味着在多线程情况下会出现错乱的情况,试想一下,如果多线程下都去 remove
列表的话,并且不按照顺序,很容易出现问题。
append
在最上面我们说到,list
的 append
操作是线程安全的,那么究竟是为什么呢?我们同样来用 dis
查看一下
8 19 LOAD_GLOBAL 0 (a) 22 LOAD_ATTR 2 (append) 25 LOAD_CONST 2 (1) 28 CALL_FUNCTION 1 31 POP_TOP
这里显然,append
也是有几条指令,势必在多线程执行的情况下也会发生交错,但是对于多线程下我们操作 append
, 我们肯定也不会在乎这个时候 list
到顺序问题了,所以我们说它的 append
是线程安全的
参考
https://stackoverflow.com/questions/6319207/are-lists-thread-safe/19728536#19728536
https://docs.python.org/3/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe
以上就是详解Python多线程下的list的详细内容,更多关于Python多线程下的list的资料请关注其它相关文章!
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。