浅谈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爬虫之抓取糗事百科代码分享
Nov 06 Python
python+ffmpeg视频并发直播压力测试
Mar 06 Python
编写多线程Python服务器 最适合基础
Sep 14 Python
对python requests发送json格式数据的实例详解
Dec 19 Python
Python中@property的理解和使用示例
Jun 11 Python
PyQt4 treewidget 选择改变颜色,并设置可编辑的方法
Jun 17 Python
使用python绘制温度变化雷达图
Oct 18 Python
使用 Python 处理3万多条数据只要几秒钟
Jan 19 Python
将tf.batch_matmul替换成tf.matmul的实现
Jun 18 Python
Python timeit模块原理及使用方法
Oct 10 Python
几款好用的python工具库(小结)
Oct 20 Python
python 制作本地应用搜索工具
Feb 27 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新手上路(十)
2006/10/09 PHP
mysql 中InnoDB和MyISAM的区别分析小结
2008/04/15 PHP
通过JavaScript或PHP检测Android设备的代码
2011/03/09 PHP
php弹出对话框实现重定向代码
2014/01/23 PHP
PHP的password_hash()使用实例
2014/03/17 PHP
实例讲解php实现多线程
2019/01/27 PHP
document节点对象的获取方式示例介绍
2013/12/24 Javascript
javascript类型转换示例
2014/04/29 Javascript
Jquery判断radio、selelct、checkbox是否选中及获取选中值方法总结
2015/04/15 Javascript
javascript省市级联功能实现方法实例详解
2015/10/20 Javascript
JavaScript中获取Radio被选中的值
2015/11/11 Javascript
深入探秘jquery瀑布流的实现
2016/01/30 Javascript
JS中mouseover和mouseout多次触发问题如何解决
2016/06/06 Javascript
JavaScript箭头(arrow)函数详解
2017/06/04 Javascript
浅谈react前后端同构渲染
2017/09/20 Javascript
ES6扩展运算符用法实例分析
2017/10/31 Javascript
深入浅析Node环境和浏览器的区别
2018/08/14 Javascript
新手入门带你学习JavaScript引擎运行原理
2019/06/24 Javascript
微信小程序使用npm包的方法步骤
2019/08/13 Javascript
js prototype和__proto__的关系是什么
2019/08/23 Javascript
JavaScript中的this妙用实例分析
2020/05/09 Javascript
tensorflow中next_batch的具体使用
2018/02/02 Python
python用户评论标签匹配的解决方法
2018/05/31 Python
Python打包方法Pyinstaller的使用
2018/10/09 Python
选择python进行数据分析的理由和优势
2019/06/25 Python
python+OpenCV实现车牌号码识别
2019/11/08 Python
使用python代码进行身份证号校验的实现示例
2019/11/21 Python
Python grpc超时机制代码示例
2020/09/14 Python
css 省略号 css3让多余的字符串消失并附加省略号的实现代码
2013/02/07 HTML / CSS
印尼最大的网上书店:Gramedia.com
2018/09/13 全球购物
Erwin Müller穆勒家居瑞士官网:您整个家庭的邮购公司
2019/12/28 全球购物
机电一体化专业应届本科生求职信
2013/09/27 职场文书
敬老院义诊活动总结
2015/05/07 职场文书
关于空气污染危害的感想
2015/08/11 职场文书
《天使的翅膀》读后感3篇
2019/12/20 职场文书
Vue+Flask实现图片传输功能
2022/04/01 Vue.js