详解Python多线程下的list

详解Python多线程下的list,第1张

详解Python多线程下的list

list 是 Python 常用的几个基本数据类型之一.正常情况下我们会对 list 有增删改查的 *** 作,显然易见不会有任何问题.那么如果我们试着在多线程下 *** 作list 会有问题吗?

多线程下的 list

安全 or 不安全? 不安全!

通常我们说的线程安全是指针对某个数据结构的所有 *** 作都是线程安全,在这种定义下,Python 常用的数据结构 list,dict,str 等都是线程不安全的

尽管多线程下的 list 是线程不安全的,但是在 append 的 *** 作下是它又是线程安全的.

如何判断线程安全呢?

对于线程安全不安全,我们可以通过极端条件下去复现,从而得出结论。比如说判断 list 是否线程安全

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_GLOBAL0 (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的资料请关注考高分网其它相关文章!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/3215674.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-10-03
下一篇 2022-10-03

发表评论

登录后才能评论

评论列表(0条)

保存