详解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编程时利用wxPython来支持多线程的方法
Apr 07 Python
Python将阿拉伯数字转换为罗马数字的方法
Jul 10 Python
Python基于动态规划算法计算单词距离
Jul 25 Python
两个使用Python脚本操作文件的小示例分享
Aug 27 Python
python相似模块用例
Mar 04 Python
Python内置模块ConfigParser实现配置读写功能的方法
Feb 12 Python
基于python代码实现简易滤除数字的方法
Jul 17 Python
用python生成1000个txt文件的方法
Oct 25 Python
对python的bytes类型数据split分割切片方法
Dec 04 Python
django-filter和普通查询的例子
Aug 12 Python
python实现拼图小游戏
Feb 22 Python
python运行脚本文件的三种方法实例
Jun 25 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
比file_get_contents稳定的curl_get_contents分享
2012/01/11 PHP
php中Ctype函数用法详解
2014/12/09 PHP
php发送html格式文本邮件的方法
2015/06/10 PHP
thinkPHP中验证码的简单使用方法
2015/12/26 PHP
php实现简单的权限管理的示例代码
2017/08/25 PHP
thinkphp ajaxfileupload实现异步上传图片的示例
2017/08/28 PHP
PHP7变量处理机制修改
2021/03/09 PHP
定义select的边框颜色
2008/04/28 Javascript
javascript读写XML实现广告轮换(兼容IE、FF)
2013/08/09 Javascript
Javascript实现返回上一页面并刷新的小例子
2013/12/11 Javascript
javascript 表格内容排序 简单操作示例代码
2014/01/03 Javascript
javascript匿名函数实例分析
2014/11/18 Javascript
轻松掌握JavaScript中的Math object数学对象
2016/05/26 Javascript
Bootstrap轮播插件中图片变形的终极解决方案 使用jqthumb.js
2016/07/10 Javascript
手机移动端实现 jquery和HTML5 Canvas的幸运大奖盘特效
2016/12/06 Javascript
BootstrapTable refresh 方法使用实例简单介绍
2017/02/20 Javascript
less简单入门(CSS 预处理语言)
2017/03/08 Javascript
微信小程序实现评论功能
2018/11/28 Javascript
Vue登录主页动态背景短视频制作
2019/09/21 Javascript
[00:42]《辉夜杯》—职业组预选赛12月3日15点 正式打响
2015/12/03 DOTA
Python和perl实现批量对目录下电子书文件重命名的代码分享
2014/11/21 Python
Python中使用logging模块打印log日志详解
2015/04/05 Python
Python与Redis的连接教程
2015/04/22 Python
python机器学习理论与实战(六)支持向量机
2018/01/19 Python
在pytorch中为Module和Tensor指定GPU的例子
2019/08/19 Python
Django 后台带有字典的列表数据与页面js交互实例
2020/04/03 Python
Python如何避免文件同名产生覆盖
2020/06/09 Python
canvas学习笔记之2d画布基础的实现
2019/02/21 HTML / CSS
基于html5绘制圆形多角图案
2016/04/21 HTML / CSS
英国工具中心:UK Tool Centre
2017/07/10 全球购物
什么是ARP(Address Resolution Protocol)地址解析协议
2013/10/31 面试题
市贸粮局召开党的群众路线教育实践活动总结大会新闻稿
2014/10/21 职场文书
离职告别感言
2015/08/04 职场文书
2016年寒假见闻
2015/10/10 职场文书
springboot @ConfigurationProperties和@PropertySource的区别
2021/06/11 Java/Android
SQL实现LeetCode(196.删除重复邮箱)
2021/08/07 MySQL