浅谈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读写Redis数据库操作示例
Mar 18 Python
Python中使用PIPE操作Linux管道
Feb 04 Python
举例讲解Python的Tornado框架实现数据可视化的教程
May 02 Python
在Python中使用mechanize模块模拟浏览器功能
May 05 Python
Python读取Excel的方法实例分析
Jul 11 Python
Python编程之序列操作实例详解
Jul 22 Python
Python随机生成均匀分布在三角形内或者任意多边形内的点
Dec 14 Python
Python DataFrame设置/更改列表字段/元素类型的方法
Jun 09 Python
python实现控制电脑鼠标和键盘,登录QQ的方法示例
Jul 06 Python
Python进阶之使用selenium爬取淘宝商品信息功能示例
Sep 16 Python
Python字典深浅拷贝与循环方式方法详解
Feb 09 Python
解决Keras中循环使用K.ctc_decode内存不释放的问题
Jun 29 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 smarty模版引擎中的缓存应用
2009/12/11 PHP
小谈php正则提取图片地址
2014/03/27 PHP
php 使用curl模拟登录人人(校内)网的简单实例
2016/06/06 PHP
Javascript和Ajax中文乱码吐血版解决方案
2009/12/21 Javascript
JavaScript控制Session操作方法
2013/01/17 Javascript
解决JQeury显示内容没有边距内容紧挨着浏览器边线
2013/12/20 Javascript
解决json日期格式问题的3种方法
2014/02/02 Javascript
使用AngularJS创建单页应用的编程指引
2015/06/19 Javascript
VueJs路由跳转——vue-router的使用详解
2017/01/10 Javascript
基本DOM节点操作
2017/01/17 Javascript
js时间戳格式化成日期格式的多种方法介绍
2017/02/16 Javascript
html+javascript+bootstrap实现层级多选框全层全选和多选功能
2017/03/09 Javascript
微信小程序自定义导航隐藏和显示功能
2017/06/13 Javascript
JavaScript监听手机物理返回键的两种解决方法
2017/08/14 Javascript
详解ES6之async+await 同步/异步方案
2017/09/19 Javascript
微信小程序methods中定义的方法互相调用的实例代码
2018/08/07 Javascript
基于JavaScript实现猜数字游戏代码实例
2020/07/30 Javascript
详解JavaScript的this指向和绑定
2020/09/08 Javascript
vue+echarts+datav大屏数据展示及实现中国地图省市县下钻功能
2020/11/16 Javascript
[52:07]完美世界DOTA2联赛PWL S3 LBZS vs access 第二场 12.10
2020/12/13 DOTA
python线程、进程和协程详解
2016/07/19 Python
Python基于回溯法子集树模板解决马踏棋盘问题示例
2017/09/11 Python
使用python验证代理ip是否可用的实现方法
2018/07/25 Python
详解Python的数据库操作(pymysql)
2019/04/04 Python
python manage.py runserver流程解析
2019/11/08 Python
python读取多层嵌套文件夹中的文件实例
2020/02/27 Python
Pytorch数据拼接与拆分操作实现图解
2020/04/30 Python
13个Pandas实用技巧,助你提高开发效率
2020/08/19 Python
Python urllib库如何添加headers过程解析
2020/10/05 Python
德国旅行、体验和活动的预订平台:Watado
2019/12/04 全球购物
如何查看在weblogic中已经发布的EJB
2012/06/01 面试题
会议接待欢迎词
2014/01/12 职场文书
户外婚礼策划方案
2014/02/08 职场文书
市场部经理岗位职责
2014/04/10 职场文书
2014年行政工作总结
2014/11/19 职场文书
高中开学感言
2015/08/01 职场文书