浅谈Python3多线程之间的执行顺序问题


Posted in Python onMay 02, 2020

一个多线程的题:定义三个线程ID分别为ABC,每个线程打印10遍自己的线程ID,按ABCABC……的顺序进行打印输出。

我的解法:

from threading import Thread, Lock


# 由_acquire解锁执行后释放_release锁
def _print(_id: str, _acquire: Lock, _release: Lock) -> None:
  for i in range(10):
    _acquire.acquire()
    print(f"id:{_id}")
    _release.release()


if __name__ == '__main__':
  # 创建三个锁供3个线程使用
  mutex1 = Lock()
  mutex2 = Lock()
  mutex3 = Lock()
  # 定义三个线程A、B、C
  # 线程A需要mutex1解锁执行后释放mutex2
  # 线程B需要mutex2解锁执行后释放mutex3
  # 线程C需要mutex3解锁执行后释放mutex1
  # 元组中第一位是自定义的线程ID,第二位是解锁需要的锁,第三位是释放的锁
  threads = [Thread(target=_print, args=[i[0], i[1], i[2]]) for i in
        [('A', mutex1, mutex2), ('B', mutex2, mutex3), ('C', mutex3, mutex1)]]
  # 把mutex2和mutex3这两把锁先用了以便阻塞线程2和线程3的执行
  mutex2.acquire()
  mutex3.acquire()
  # 接下来只有线程A可以先执行是因为mutex1并没有被占用
  # 线程B和线程C需要分别等待着锁2和锁3的释放才能继续执行
  [thr.start() for thr in threads]
  [thr.join() for thr in threads]

补充知识:python线程执行代码封装和执行顺序

线程-注意点

1. 线程执行代码的封装

通过上一小节,能够看出,通过使用threading模块能完成多任务的程序开发,为了让每个线程的封装性更完美,所以使用threading模块时,往往会定义一个新的子类class,只要继承threading.Thread就可以了,然后重写run方法

示例如下:

#coding=utf-8
import threading
import time

class MyThread(threading.Thread):
  def run(self):
    for i in range(3):
      time.sleep(1)
      msg = "I'm "+self.name+' @ '+str(i) #name属性中保存的是当前线程的名字
      print(msg)


if __name__ == '__main__':
  t = MyThread()
  t.start()

说明

python的threading.Thread类有一个run方法,用于定义线程的功能函数,可以在自己的线程类中覆盖该方法。而创建自己的线程实例后,通过Thread类的start方法,可以启动该线程,交给python虚拟机进行调度,当该线程获得执行的机会时,就会调用run方法执行线程。

2. 线程的执行顺序

#coding=utf-8
import threading
import time

class MyThread(threading.Thread):
  def run(self):
    for i in range(3):
      time.sleep(1)
      msg = "I'm "+self.name+' @ '+str(i)
      print(msg)
def test():
  for i in range(5):
    t = MyThread()
    t.start()
if __name__ == '__main__':
  test()

执行结果:(运行的结果可能不一样,但是大体是一致的)

I'm Thread-1 @ 0
  I'm Thread-2 @ 0
  I'm Thread-5 @ 0
  I'm Thread-3 @ 0
  I'm Thread-4 @ 0
  I'm Thread-3 @ 1
  I'm Thread-4 @ 1
  I'm Thread-5 @ 1
  I'm Thread-1 @ 1
  I'm Thread-2 @ 1
  I'm Thread-4 @ 2
  I'm Thread-5 @ 2
  I'm Thread-2 @ 2
  I'm Thread-1 @ 2
  I'm Thread-3 @ 2

说明

从代码和执行结果我们可以看出,多线程程序的执行顺序是不确定的。当执行到sleep语句时,线程将被阻塞(Blocked),到sleep结束后,线程进入就绪(Runnable)状态,等待调度。而线程调度将自行选择一个线程执行。上面的代码中只能保证每个线程都运行完整个run函数,但是线程的启动顺序、run函数中每次循环的执行顺序都不能确定。

3. 总结

每个线程默认有一个名字,尽管上面的例子中没有指定线程对象的name,但是python会自动为线程指定一个名字。

当线程的run()方法结束时该线程完成。

无法控制线程调度程序,但可以通过别的方式来影响线程调度的方式。

以上这篇浅谈Python3多线程之间的执行顺序问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
使用python实现拉钩网上的FizzBuzzWhizz问题示例
May 05 Python
Python实现删除文件但保留指定文件
Jun 21 Python
python Django模板的使用方法
Jan 14 Python
Python中operator模块的操作符使用示例总结
Jun 28 Python
django 在原有表格添加或删除字段的实例
May 27 Python
win10下tensorflow和matplotlib安装教程
Sep 19 Python
Django框架使用内置方法实现登录功能详解
Jun 12 Python
python pandas获取csv指定行 列的操作方法
Jul 12 Python
使用Python三角函数公式计算三角形的夹角案例
Apr 15 Python
Python实现Keras搭建神经网络训练分类模型教程
Jun 12 Python
numpy 矩阵形状调整:拉伸、变成一位数组的实例
Jun 18 Python
Python定时任务框架APScheduler原理及常用代码
Oct 05 Python
python继承threading.Thread实现有返回值的子类实例
May 02 #Python
Python3-异步进程回调函数(callback())介绍
May 02 #Python
浅谈Python中threading join和setDaemon用法及区别说明
May 02 #Python
判断Threading.start新线程是否执行完毕的实例
May 02 #Python
python中threading开启关闭线程操作
May 02 #Python
浅谈python3打包与拆包在函数的应用详解
May 02 #Python
构建高效的python requests长连接池详解
May 02 #Python
You might like
PHP调用三种数据库的方法(2)
2006/10/09 PHP
php中的strpos使用示例
2014/02/27 PHP
PHP二维关联数组的遍历方式(实例讲解)
2017/10/18 PHP
PHP PDOStatement::columnCount讲解
2019/01/30 PHP
学习ExtJS TextField常用方法
2009/10/07 Javascript
jQuery中使用了document和window哪些属性和方法小结
2011/09/13 Javascript
js设置组合快捷键/tabindex功能的方法
2013/11/21 Javascript
jQuery 计算iframe 窗口大小的方法
2014/05/13 Javascript
Node.js编码规范
2014/07/14 Javascript
跟我学习javascript创建对象(类)的8种方法
2015/11/20 Javascript
Bootstrap对话框使用实例讲解
2016/09/24 Javascript
JS中常用的正则表达式
2016/09/29 Javascript
浅析使用BootStrap TreeView插件实现灵活配置快递模板
2016/11/28 Javascript
JS中如何实现复选框全选功能
2016/12/19 Javascript
详解Node.js实现301、302重定向服务
2017/04/07 Javascript
Angular 2父子组件数据传递之局部变量获取子组件其他成员
2017/07/04 Javascript
实例详解JavaScript中setTimeout函数的执行顺序
2017/07/12 Javascript
Webpack 4如何动态切割JS注入文件名详解
2019/07/09 Javascript
微信小程序自定义弹出模态框禁止底部滚动功能
2020/03/09 Javascript
Python的Django中将文件上传至七牛云存储的代码分享
2016/06/03 Python
python读取中文txt文本的方法
2018/04/12 Python
python3 pygame实现接小球游戏
2019/05/14 Python
Django 路由层URLconf的实现
2019/12/30 Python
selenium切换标签页解决get超时问题的完整代码
2020/08/30 Python
Linux系统下升级pip的完整步骤
2021/01/31 Python
澳大利亚领先的在线礼品网站:Gifts Australia
2020/08/15 全球购物
护士的岗位职责
2013/12/04 职场文书
酒店实习个人鉴定
2013/12/07 职场文书
新闻专业个人求职信
2013/12/19 职场文书
拾金不昧的表扬信
2014/01/16 职场文书
法学个人求职信范文
2014/01/27 职场文书
父母寄语大全
2014/04/12 职场文书
安全保证书范文
2014/04/29 职场文书
财务管理专业毕业生求职信
2014/06/02 职场文书
医药销售自我评价200字
2014/09/11 职场文书
http通过StreamingHttpResponse完成连续的数据传输长链接方式
2022/02/12 Python