浅谈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备份文件的脚本
Aug 11 Python
python 域名分析工具实现代码
Jul 15 Python
Python中的数据对象持久化存储模块pickle的使用示例
Mar 03 Python
用Python实现命令行闹钟脚本实例
Sep 05 Python
Python 2与Python 3版本和编码的对比
Feb 14 Python
Python断言assert的用法代码解析
Feb 03 Python
TensorFlow实现AutoEncoder自编码器
Mar 09 Python
pandas进行数据的交集与并集方式的数据合并方法
Jun 27 Python
python利用tkinter实现屏保
Jul 30 Python
详解如何在PyCharm控制台中输出彩色文字和背景
Aug 17 Python
python 利用toapi库自动生成api
Oct 19 Python
Django与数据库交互的实现
Jun 03 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 转义使用详解
2013/07/15 PHP
解析VS2010利用VS.PHP插件调试PHP的方法
2013/07/19 PHP
怎么在Windows系统中搭建php环境
2013/08/31 PHP
浅谈PHP中pack、unpack的详细用法
2018/03/12 PHP
使用jQuery全局事件ajaxStart为特定请求实现提示效果的代码
2010/12/30 Javascript
JavaScript 更严格的相等 [译]
2012/09/20 Javascript
Ext中下拉列表ComboBox组件store数据格式用法介绍
2013/07/15 Javascript
改变状态栏文字的js代码
2014/06/13 Javascript
java和javascript获取word文档的书签位置对比
2014/06/19 Javascript
JQuery实现可直接编辑的表格
2015/04/16 Javascript
JavaScript tab选项卡插件实例代码
2016/02/23 Javascript
Node.js的基本知识简单汇总
2016/09/19 Javascript
详解Angular.js中$http拦截器的介绍及使用
2017/07/04 Javascript
AngularJS表单验证功能
2017/10/19 Javascript
nodejs async异步常用函数总结(推荐)
2017/11/17 NodeJs
JavaScript中EventLoop介绍
2018/01/22 Javascript
解决vue 绑定对象内点击事件失效问题
2018/09/05 Javascript
详解javascript函数写法大全
2019/03/25 Javascript
vue.js实现回到顶部动画效果
2019/07/31 Javascript
JS中的算法与数据结构之链表(Linked-list)实例详解
2019/08/20 Javascript
openlayers实现地图测距测面
2020/09/25 Javascript
微信小程序实现倒计时功能
2020/11/19 Javascript
[00:10]DOTA2全国高校联赛速递
2018/05/30 DOTA
python写xml文件的操作实例
2014/10/05 Python
Python编程之变量赋值操作实例分析
2017/07/24 Python
利用Python+Java调用Shell脚本时的死锁陷阱详解
2018/01/24 Python
PyQt 实现使窗口中的元素跟随窗口大小的变化而变化
2019/06/18 Python
使用浏览器访问python写的服务器程序
2019/10/10 Python
对tensorflow 中tile函数的使用详解
2020/02/07 Python
N.Peal官网:来自伦敦的高档羊绒品牌
2018/10/29 全球购物
法国发饰品牌:Alexandre De Paris
2018/12/04 全球购物
生日寿宴答谢词
2014/01/19 职场文书
节约用水倡议书
2014/04/16 职场文书
2015年幼儿教师个人工作总结
2015/05/20 职场文书
会计岗位工作总结
2015/08/12 职场文书
用php如何解决大文件分片上传问题
2021/07/07 PHP