详解Python多线程下的list


Posted in Python onJuly 03, 2020

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)

有时候一次运行并不一定就会出错,多次重试之后会出现类似下面的错误

详解Python多线程下的list

很显然这种操作方式不具有普适性,如果要是欧气太强,说不定会一直不出现异常。

那么出了这种方式,有没有比较简单有效的方法吗?答案是有的

dis

dis 库是 Python 自带的一个库,可以用来分析字节码。这里我们需要有这样的认识,字节码的每一行都是一个原子操作,多线程切换就是以原子操作为单位的,如果一个操作需要两行字节码就说明它是线程不安全的

remove

这里我们先看一下上面 listremove 操作

>>> 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的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python 判断自定义对象类型
Mar 21 Python
python绘制热力图heatmap
Mar 23 Python
django 外键model的互相读取方法
Dec 15 Python
在Python中关于使用os模块遍历目录的实现方法
Jan 03 Python
解决python打不开文件(文件不存在)的问题
Feb 18 Python
Pythony运维入门之Socket网络编程详解
Apr 15 Python
Python多版本开发环境管理工具介绍
Jul 03 Python
Python CSV文件模块的使用案例分析
Dec 21 Python
在pycharm中使用matplotlib.pyplot 绘图时报错的解决
Jun 01 Python
Python实现Canny及Hough算法代码实例解析
Aug 06 Python
Django静态文件加载失败解决方案
Aug 26 Python
彻底搞懂python 迭代器和生成器
Sep 07 Python
Python 字符串池化的前提
Jul 03 #Python
Pycharm打开已有项目配置python环境的方法
Jul 03 #Python
使用Dajngo 通过代码添加xadmin用户和权限(组)
Jul 03 #Python
windows支持哪个版本的python
Jul 03 #Python
Django Form设置文本框为readonly操作
Jul 03 #Python
完美解决TensorFlow和Keras大数据量内存溢出的问题
Jul 03 #Python
Keras 在fit_generator训练方式中加入图像random_crop操作
Jul 03 #Python
You might like
PHP对象转换为数组函数(递归方法)
2012/02/04 PHP
php cli 小技巧
2013/06/03 PHP
php商品对比功能代码分享
2015/09/24 PHP
PHP静态成员变量和非静态成员变量详解
2017/02/14 PHP
PHP魔术方法之__call与__callStatic使用方法
2017/07/23 PHP
详解json在php中的应用
2018/09/30 PHP
基于jquery的滚动新闻列表
2010/06/19 Javascript
js自动查找select下拉的菜单并选择(示例代码)
2014/02/26 Javascript
javascript解析json数据的3种方式
2014/05/08 Javascript
jQuery中each()方法用法实例
2014/12/27 Javascript
javascript操作Cookie(设置、读取、删除)方法详解
2015/03/18 Javascript
jQuery基于ajax实现带动画效果无刷新柱状图投票代码
2015/08/10 Javascript
js从外部获取图片的实现方法
2016/08/05 Javascript
AngularJS 工作原理详解
2016/08/18 Javascript
JQuery遍历元素的后代和同胞实现方法
2016/09/18 Javascript
详解nodejs异步I/O和事件循环
2017/06/07 NodeJs
jQuery简单实现对数组去重及排序操作实例
2017/10/31 jQuery
React Native使用百度Echarts显示图表的示例代码
2017/11/07 Javascript
Nuxt.js实现校验访问浏览器类型的中间件
2018/08/24 Javascript
vue.extend与vue.component的区别和联系
2018/09/19 Javascript
微信jssdk逻辑在vue中的运用详解
2018/11/14 Javascript
[00:52]DOTA2齐天大圣预告片
2016/08/13 DOTA
python表格存取的方法
2018/03/07 Python
Python 使用PIL中的resize进行缩放的实例讲解
2018/08/03 Python
关于python列表增加元素的三种操作方法
2018/08/22 Python
python实现维吉尼亚算法
2019/03/20 Python
python3 深浅copy对比详解
2019/08/12 Python
Python 字符串处理特殊空格\xc2\xa0\t\n Non-breaking space
2020/02/23 Python
Python GUI库PyQt5样式QSS子控件介绍
2020/02/25 Python
python sklearn包——混淆矩阵、分类报告等自动生成方式
2020/02/28 Python
利用CSS3实现自定义滚动条代码分享
2016/08/18 HTML / CSS
英国领先的男士服装和时尚零售商:Burton
2017/01/09 全球购物
党员入党表决心的话
2014/03/11 职场文书
2016民族团结先进个人事迹材料
2016/02/26 职场文书
2019奶茶店创业计划书范本!
2019/07/15 职场文书
Springboot/Springcloud项目集成redis进行存取的过程解析
2021/12/04 Redis