Python多线程—threading模块
参考:《Python核心编程》
threading 模块的Thread 类是主要的执行对象,而且,使用Thread类可以有很多方法来创建线程,这里介绍以下两种方法:
- 创建 Thread 实例,传给它一个函数。
- 派生 Thread 的子类,并创建子类的实例。
如果是有面向对象接口需求的,第二种方法更加符合。
1、创建Thread的实例,传给它一个函数
示例代码:
from threading import Thread
from time import sleep, ctimeloops = [4, 2]def loop(nloop, nsec):print("start loop ", nloop, " at ", ctime())sleep(nsec)print("nloop ", nloop, " done at ", ctime())def main():threads = []print("starting at: ", ctime())# create all threadsfor i in range(len(loops)):t = Thread(target=loop, args=(i, loops[i]))threads.append(t)# start threadfor i in range(len(loops)):threads[i].start()# wait for all threads to finishfor i in range(len(loops)):threads[i].join()print("all DONE at: ", ctime())if __name__ == "__main__":main()
执行脚本:
$ python myThread.py
starting at: Sat Jan 20 17:22:28 2024
start loop 0 at Sat Jan 20 17:22:28 2024
start loop 1 at Sat Jan 20 17:22:28 2024
nloop 1 done at Sat Jan 20 17:22:30 2024
nloop 0 done at Sat Jan 20 17:22:32 2024
all DONE at: Sat Jan 20 17:22:32 2024
- 在上述代码中,当实例化每个 Thread 对象时,把函数(target)和参数(args)传进去,然后得到返回的 Thread 实例。实例化 Thread 后,线程不会立即开始执行,而是把启动的指挥权交给程序员,这是一个非常有用的同步功能,尤其是当你并不希望线程开始立即执行时。
- 当所有线程都分配完成之后,通过调用每个线程的 start()方法让它们开始执行。
- join()方法将等待当前(或所有)线程结束后再往下执行。一旦线程启动,它们就会一直执行,直到给定的函数完成后退出。如果主线程还有其他事情要去做,而不是等待这些线程完成(例如其他处理或者等待新的客户端请求),就可以不调用 join()。join()方法只有在你需要等待线程完成的时候才是有用的。比如,如果将 join() 方法所在的 for 循环注释掉,那么执行脚本后将会得到下面这样的结果:
$ python myThread.py
starting at: Sat Jan 20 17:45:16 2024
start loop 0 at Sat Jan 20 17:45:16 2024
start loop 1 at Sat Jan 20 17:45:16 2024
all DONE at: Sat Jan 20 17:45:16 2024
nloop 1 done at Sat Jan 20 17:45:18 2024
nloop 0 done at Sat Jan 20 17:45:20 2024
2、派生 Thread 的子类,并创建子类的实例
当创建线程时使用子类要相对更容易阅读,而且如上所述,当你需要一个更加符合面向对象的接口时,
会选择这种方法。下面的示例中将对 Thread 子类化,而不是直接对其实例化。这将使我们在定制线程对象时拥有更多的灵活性,也能够简化线程创建的调用过程。
示例代码:
from threading import Thread
from time import sleep, ctimeloops = [4, 2]class MyThread(Thread):def __init__(self, func, args, name=''):Thread.__init__(self) # 调用基类构造方法self.func = funcself.args = argsself.name = namedef run(self):self.func(*self.args)def loop(nloop, nsec):print("start loop ", nloop, " at ", ctime())sleep(nsec)print("loop ", nloop, "done at ", ctime())def main():threads = []# 创建线程for i in range(len(loops)):t = MyThread(func=loop, args=(i,loops[i]), name=loop.__name__)threads.append(t)# 启动线程for i in range(len(loops)):threads[i].start()# 等待所有线程执行完毕for i in range(len(loops)):threads[i].join()print("all DONE at ", ctime())if __name__ == "__main__":main()
执行脚本:
$ python myThread2.py
start loop 0 at Sat Jan 20 18:49:51 2024
start loop 1 at Sat Jan 20 18:49:51 2024
loop 1 done at Sat Jan 20 18:49:53 2024
loop 0 done at Sat Jan 20 18:49:55 2024
all DONE at Sat Jan 20 18:49:55 2024
- MyThread 子类的构造函数必须先调用其基类的构造函数。
- 当创建新线程时,Thread 类的代码将调用 MyThread 对象,此时会调用__run__()这个特殊方法。
补:Thread 对象的属性和方法
相关文章:

Python多线程—threading模块
参考:《Python核心编程》 threading 模块的Thread 类是主要的执行对象,而且,使用Thread类可以有很多方法来创建线程,这里介绍以下两种方法: 创建 Thread 实例,传给它一个函数。派生 Thread 的子类…...
mysql limit
语法 SELECT * FROM TABLE_NAME LIMIT 起始位置,偏移量注: 起始位置从0开始 示例 查询的第1条数据到第100条数据 limit 0,100查询的第101条数据到第200条数据 limit 100,100注意不要用 limit 101,100示例2 limit 语句应放在order by语句后面执行 …...

解决国内Linux服务器无法使用Github的方法
解决思路:修改Host https://www.ipaddress.com/ 利用上面的网站查询github.com和raw.githubusercontent.com的DNS解析的IP地址 最后,修改服务器的/etc/hosts 添加如下两行: 140.82.112.3 github.com 185.199.108.133 raw.githubuserconte…...
动态规划基础(二)最长公共子序列 LCS
讲解求两个串中最长的公共的子序列长度或输出子序列等 poj1458 题目大意 给定两个字符串,要求输出两个字符串中最长公共子序列长度 思路 我们定义 a [ i ] [ j ] a[i][j] a[i][j]为,当字串 s t r 1 str1 str1到 i i i位置,字串 s t r 2 s…...

React配置src根目录@
文章目录 1.打开webpack配置文件2.配置webpack 1.打开webpack配置文件 yarn eject or npm run eject 如果报错了记得提前 git commit一下 2.配置webpack 找到 webpack.config.js 文件在 webpack.config.js 文件中找到 alias 配置在alias里添加: path.resolve(src) , 或者 : pa…...

SQL Povit函数使用及实例
PIVOT函数常用于数据的行转列,同时也可以用此函数实现类似于Excel中的数据透视表的效果。 PIVOT函数 PIVOT 函数的基本语法如下: -- PIVOT 语法 SELECT <非透视的列>,[第一个透视的列] AS <列名称>,[第二个透视的列] AS <列名称>,.…...

Lite AD的安装
1、Lite AD的安装及配置 Lite AD流程: (1)创建一个新的Windows 10,安装tools,再安装ITA组件(安装Lite AD会自动安装VAG/VLB) (2)创建一个新的Windows 10,安…...

限流算法之流量控制的平滑之道:滑动时间窗算法
文章目录 引言简介优点缺点样例样例图样例代码 应用场景结论 引言 在互联网应用中,流量控制是一个重要的组件,用于防止系统过载和保护核心资源。常见的限流算法包括固定窗口算法和滑动时间窗算法。本文将重点介绍滑动时间窗算法,并分析其优缺…...

C语言数据结构——顺序表
(图片由AI生成) 0.前言 在程序设计的世界里,数据结构是非常重要的基础概念。本文将专注于C语言中的一种基本数据结构——顺序表。我们将从数据结构的基本概念讲起,逐步深入到顺序表的内部结构、分类,最后通过一个实…...

网络安全:守护数字世界的盾牌
在当今数字化的时代,网络已经渗透到我们生活的方方面面。从社交媒体到在线银行,从在线购物到工作文件传输,网络几乎无处不在。然而,随着网络的普及,网络安全问题也日益凸显。那么,如何确保我们的数字资产安…...
vue3hooks的使用
hook是钩子的意思,看到“钩子”是不是就想到了钩子函数?事实上,hooks 还真是函数的一种写法。 vue3 借鉴 react hooks 开发出了 Composition API ,所以也就意味着 Composition API 也能进行自定义封装 hooks。 vue3 中的 hooks …...

elementUI+el-upload 上传、下载、删除文件以及文件展示列表自定义为表格展示
Upload 上传组件的使用 官方文档链接使用el-upload组件上传文件 具体参数说明,如何实现上传、下载、删除等功能获取文件列表进行file-list格式匹配代码 文件展示列表自定义为表格展示 使用的具体参数说明文件大小展示问题(KB/MB)文件下载代码…...

供应链安全项目in-toto开源框架详解
引言:in-toto 是一个开源框架,能够以密码学的方式验证构件生产路径上的每个组件和步骤。它可与主流的构建工具、部署工具进行集成。in-toto已经被CNCF技术监督委员会 (Technical Oversight Committee,TOC)接纳为CNCF孵化项目。 1. 背景 由于…...

自己是如何使用单元测试
前言 自己是如何使用单元测试 进行单元测试能够让我们在编写方法的具体实现代码后,能清晰地看到其是否能实现预期的功能,有助于我们及时修正自己方法中存在的bug,以免在后续使用到某方法时出现意想不到的错误。 一、引入单元测试所使用的依赖…...

第二百七十八回
文章目录 1. 概念介绍2. 使用方法2.1 DropdownMenu2.1 DropdownMenuEntry 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何禁止页面跟随手机自动旋转"相关的内容,本章回中将介绍DropdownMenu组件.闲话休提,让我们一起Talk Flutter吧。 1.…...

Java 内存模型深度解析
优质博文:IT-BLOG-CN 一、并发编程模型的两个关键问题 【1】并发中常见的两个问题:线程之间如何通信及线程之间如何同步。通信是指线程之间以何种机制来交换信息。在命令式编程中,线程之间的通信机制有两种:内存共享和消息传递&…...

python爬取图片(thumbURL和html文件标签分别爬取)
当查看源代码,发现网址在thumbURL之后时,用此代码: # 当查看源代码,发现网址在thumbURL之后时,用此代码:import requestsheaders {User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121…...
MySQL、Oracle 常用SQL:建表、建视图、数据增删改查、常用condition
目录 1 MySQL、Oracle 建表语句整理1.1 MySQL 建表1.2 Oracle 建表1.3 补充1.3.1 主键:新增、删除1.3.2 字段:新增、修改、删除 2 MySQL、Oracle 建视图3 数据:增删改查3.1 插入数据3.1.1 MySQL、Oracle 插入一条数据3.1.2 MySQL、Oracle 插入…...

Docker(八)高级网络配置
作者主页: 正函数的个人主页 文章收录专栏: Docker 欢迎大家点赞 👍 收藏 ⭐ 加关注哦! 高级网络配置 注意:本章属于 Docker 高级配置,如果您是初学者,您可以暂时跳过本章节,直接学习…...
VUE--- ref refs
ref & refs 的作用:用于获取dom元素或组件实例,也可用于组件组件间数据的获取和修改 ref & refs 与querySelector的区别: ● ref & refs 查找的范围是当前组件内,更加精确稳定 ● querySelector 查找的范围是整个页面…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...

【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...