并发编程-线程
并发编程-线程
- 一个进程是操作系统中运行的一个任务,进程独立拥有CPU、内存等资源
- 一个线程是一个进程中运行的一个任务,线程之间共享CPU、内存等资源,进程里的每一个任务都是线程。
线程创建
创建线程:使用threading模块中的Thread类来创建线程
- target表示线程执行的任务
- args表示任务的参数,是一个元组
- start()方法指启动线程
- join()方法指等待线程结束
from threading import Threaddef task(count:int):...thread1 = Thread(target=task, args=(10,)) # 创建子线程thread1
thread1.start() # 启动子线程
启动两个线程执行task任务
from threading import Threaddef task(count: int):for i in range(count):print(i)thread1 = Thread(target=task, args=(10,))
thread2 = Thread(target=task, args=(20,))thread1.start() # 启动线程1
thread2.start() # 启动线程2
print("main thread is end") # 执行到此处,主线程无任务,自行结束
输出结果:
0
1
2
3
4
5
06main thread is end78
9
1
2
3
4
5
6
7
8
9
等待主线程结束:
from threading import Threaddef task():for i in range(10):print(i)thread1 = Thread(target=task)
thread2 = Thread(target=task)thread1.start()
thread2.start()
thread1.join() # 等待线程执行结束
thread2.join() # 等待线程执行结束
print("main thread is end") # 等到线程1和线程2任务执行完毕,主线程才会结束
输出结果:
0
1
2
3
4
50
6
7
8
9
12
3
4
5
6
7
8
9
main thread is end
通过继承创建线程
通过继承Thread类来创建线程
打印混乱的原因:多线程执行时,print函数打印内容后会再打印换行,导致换行来不及打印,出现打印混乱
解决办法:行尾手动加换行,print函数end参数设置为空字符串
print(f"{self.name} - {i}\n", end="")
from threading import Threadclass MyThread(Thread):def run(self) -> None:# 线程的任务脚本pass
import time
from threading import Threadclass MyThread(Thread):def __init__(self, name: str, count: int):super().__init__()# 该方法已弃用,使用name属性替换# self.setName()self.name = name # 设置线程名称self.count = countdef run(self) -> None:# 线程的任务脚本for i in range(self.count):print(f"{self.name} - {i}\n", end="")# 休眠10毫秒time.sleep(0.01)t1 = MyThread("a", 10)
t2 = MyThread("b", 10)
t1.start()
t2.start()
输出结果:
D:\Python3.11\python.exe F:/Code/python_code/high_python/python_advance/thread/demo01_class.py
a - 0
b - 0
a - 1
b - 1
b - 2
a - 2
a - 3
b - 3
b - 4
a - 4
b - 5
a - 5
b - 6
a - 6
b - 7
a - 7
b - 8
a - 8
b - 9
a - 9
守护线程
主线程结束,守护线程会自动结束,这就叫守护线程
- 守护线程会在主线程结束时候自动结束
- 主线程则需要等待到所有的非守护线程结束才能结束
- 守护线程一般用于非关键性的线程,比如:日志
from threading import Threaddef task():for i in range(10):print(i)thread = Thread(target=task, daemon=True)
thread.start()
输出结果:
0
Process finished with exit code 0
等待线程结束
from threading import Threaddef task():for i in range(10):print(i)thread = Thread(target=task, daemon=True)
thread.start()
thread.join()
输出结果:
D:\Python3.11\python.exe F:/Code/python_code/high_python/python_advance/thread/demo03_daemon_thread.py
0
1
2
3
4
5
6
7
8
9Process finished with exit code 0
继承类设置守护线程
class MyThread(Thread):def __init__(self, name: str, count: int):super().__init__()# 该方法已弃用,使用name属性替换# self.setName()self.name = name # 设置线程名称self.count = countself.daemon = Truedef run(self) -> None:# 线程的任务脚本for i in range(self.count):print(f"{self.name} - {i}\n", end="")# 休眠10毫秒time.sleep(0.01)t1 = MyThread("a", 10)
t2 = MyThread("b", 10)
t1.start()
t2.start()
t1.join() # 等待t1结束,结束主线程
线程安全队列
queue模块中的Queue类提供了线程安全队列功能
- put(item, block=False) # 队列元素满时,不阻塞,会抛出异常,为True时,会让线程阻塞等待, 可能会导致线程卡死
- put(item, timeout=3) # 队列元素满时,等待timeout时间,如果超出时间则抛出异常
- get(block=False) # 从队列取元素,如果队列为空则不阻塞,会抛出异常
- get(timeout=10) # 从队列取元素,如果队列为空则则赛等待10秒,超时抛出异常
- qsize() # 队列大小
- empty() # 判断队列是否为空
- full() # 判断队列是否满的
生产者消费者线程实例
from threading import Thread
from queue import Queueclass Producer(Thread):"""生产者"""def __init__(self, name: str, count: int, queue: Queue) -> None:super(Producer, self).__init__()# 线程自带属性self.name = name# 自定义属性self.count = countself.queue = queuedef run(self) -> None:for n in range(self.count):msg = f"{self.name} - {n}"self.queue.put(msg, block=True)class Consumer(Thread):"""消费者"""def __init__(self, name: str, queue: Queue) -> None:super().__init__()self.name = nameself.daemon = Trueself.queue = queuedef run(self) -> None:while True:msg = self.queue.get(block=True)print(f"{self.name} - {msg}\n", end="")queue = Queue(maxsize=3)
threads = [Producer("p1", 10, queue),Producer("p2", 10, queue),Producer("p3", 10, queue),Consumer("c1", queue),Consumer("c2", queue),
]for t in threads:t.start()
线程池
- 线程的创建和销毁相对比较耗费资源
- 频繁的创建和销毁线程不利于高性能
- 线程池是python提供的便于线程管理和提高性能的工具
python提供两个类来管理线程
concurrent.futures.ThreadPoolExecutor
- submit() # 启动/执行一个任务,返回结果是一个Future对象
- map() # 多个任务执行,将不同参数分配到每一个任务中
- shutdown() # 关闭线程池
- Future
- result() # 任务执行结果
- exception() # 任务异常信息
方式一:适用于不同任务
from concurrent.futures import ThreadPoolExecutor
import timedef task(name: str):print(f"{name} - step 1\n", end="")time.sleep(1)print(f"{name} - step 2\n", end="")return f"{name} complete"with ThreadPoolExecutor() as executor:result_1 = executor.submit(task, "A")result_2 = executor.submit(task, "B")print(result_1.result()) # result()会等待有结果再返回print(result_2.result())"""
A - step 1
B - step 1
A - step 2
A complete
B - step 2
B complete
"""
方式二:map()
适用于同一任务,不同参数
from concurrent.futures import ThreadPoolExecutor
import timedef task(name: str) -> str:print(f"{name} - step 1\n", end="")time.sleep(1)print(f"{name} - step 2\n", end="")return f"{name} complete"with ThreadPoolExecutor() as executor:results = executor.map(task, ["C", "D"])for r in results:print(r)"""
C - step 1
D - step 1
D - step 2
C - step 2
C complete
D complete
"""
多线程案例:下载图片
from concurrent.futures import ThreadPoolExecutor
from urllib.request import urlopen, Request
import osdef download_img(url: str):site_url = Request(url, headers={})with urlopen(site_url) as web_file:img_data = web_file.read()if not img_data:raise Exception(f"Error: can not load the image from {url}")file_name = os.path.basename(url)with open(file_name, "wb") as f:f.write(img_data)return "Download image successfully, {}".format(url)urls = ["https://img0.bdstatic.com/static/searchresult/img/baseimg3_4f26a23.png",# "..."
]
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36","content-type": "Content-Type: image/jpeg"
}
with ThreadPoolExecutor() as ececutor:results = ececutor.map(download_img, urls)for r in results:print(r)
执行结果:
PS F:\Code\python_code\high_python\python_advance\thread> python .\thread_pool_demo.py
Download image successfully, https://img0.bdstatic.com/static/searchresult/img/baseimg3_4f26a23.png
相关文章:
并发编程-线程
并发编程-线程 一个进程是操作系统中运行的一个任务,进程独立拥有CPU、内存等资源一个线程是一个进程中运行的一个任务,线程之间共享CPU、内存等资源,进程里的每一个任务都是线程。 线程创建 创建线程:使用threading模块中的Th…...
图解LeetCode——剑指 Offer 34. 二叉树中和为某一值的路径
一、题目 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。叶子节点 是指没有子节点的节点。 二、示例 2.1> 示例 1: 【输入】root [5,4,8,11,null,13,4,7,2,null,null,5,1], t…...
使用Python免费试用最新Openai API
一、背景介绍 3月2日凌晨,OpenAI放出了真正的ChatGPT API,不是背后的GPT-3.5大模型,是ChatGPT的本体模型!ChatGPT API价格为1k tokens/$0.002,等于每输出100万个单词,价格才2.7美金(约18元人民…...
04、启动 SVN 服务器端程序
启动 SVN 服务器端程序1 概述2 用命令行单项目启动2.1 采用 svnserve 命令2.2 验证服务是否启动2.3 命令行方式的缺陷3 注册Windows服务3.1 注册服务的命令3.2 命令说明3.3 启动服务1 概述 SVN 服务器和 Tomcat 服务器,Nexus 服务器一样, 必须处于运行状态才能响应…...
jsp船舶引航计费网站Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 JSP船舶引航计费网站是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0&…...
Allegro如何画半圆形的线操作指导
Allegro如何画半圆形的线操作指导 在用Allegro设计PCB的时候,在某些应用场合会需要画半圆形,如下图 如何画半圆形,具体操作如下 点击Add点击Arc w/Radius...
【强烈建议收藏:MySQL面试必问系列之SQL语句执行专题】
一.知识回顾 之前的文章我们一起学习了MySQL面试必问系列之事务专题、锁专题,没有学习的小伙伴可以直接通过该链接地址直接访问,MYSQL你真的了解吗专栏的文章,接下来我们就一起来学习一下MySQL中SQL语句的执行流程,看看你掌握的怎…...
详解Linux下的环境变量以及C++库文件和头文件、python库的配置
目录 Linux环境变量配置基本步骤 1.查看环境变量 2.设置环境变量 3.永久性设置环境变量 4.使用环境变量 C 库文件和头文件环境变量配置 1.配置so库文件的环境变量 2.配置头文件的环境变量 Python库环境变量配置 Linux配置执行文件环境变量 我们都习惯在Windows 上配置…...
企业级分布式数据库 - GaussDB介绍
目录 什么是GaussDB 简介 应用场景 产品架构 产品优势 安全 责任共担 身份认证与访问控制 数据保护技术 审计与日志 监控安全风险 故障恢复 认证证书 GaussDB与其他服务的关系 约束与限制 计费模式 什么是GaussDB …...
Linux I2C 驱动实验
目录 一、Linux I2C 驱动简介 1、I2C 总线驱动 2、I2C 设备驱动 1、 i2c_client 结构体 2、 i2c_driver 结构体 二、硬件分析 三、设备树编写 1、pinctrl_i2c1 2、在 i2c1 节点追加 ap3216c 子节点 3、验证 四、 代码编写 1、makefile 2、ap3216c.h 3、ap3216c.c …...
DC-DC模块电源隔离直流升压高压稳压输出5v12v24v转60v100v110v150v220v250v300v400v500v
特点效率高达80%以上1*1英寸标准封装单电压输出稳压输出工作温度: -40℃~85℃阻燃封装,满足UL94-V0 要求温度特性好可直接焊在PCB 上应用HRB 0.2~10W 系列模块电源是一种DC-DC升压变换器。该模块电源的输入电压分为:4.5~9V、9~18V、及18~36VDC标准&#…...
EF有几种模式,EF的三种模式分别是什么?
EF有几种模式,EF的三种模式分别是什么? 第一种:DataBase First DataBase First传统的表驱动方式创建EDM,然后通过EDM生成模型和数据层代码。除生成实体模型和自跟踪实现模型,还支持生成轻型DbContext。 解释…...
数据可视化展示:打工人常见职业病,颈腰椎病占比最高达66.51%
身体健康才是一切的根本。只有身体健健康康才能更好的去享受世间的美好,无论是谁都应当注重身体健康,而不是无度的挥霍它! 良好的身体,释放给工作,健壮的体魄,享受美好生活,良好的心态ÿ…...
【食品图像识别】Large Scale Visual Food Recognition
1 引言 视觉智能部与中科院计算所于2020-2021年度展开了《细粒度菜品图像识别和检索》科研课题合作,本文系双方联合在IEEE T-PAMI2023发布论文《Large Scale Visual Food Recognition》 (Weiqing Min, Zhiling Wang, Yuxin Liu, Mengjiang Luo, Liping Kang, Xiaom…...
RAN-in-the-Cloud:为 5G RAN 提供云经济性
RAN-in-the-Cloud:为 5G RAN 提供云经济性 5G 部署在全球范围内一直在加速。 许多电信运营商已经推出了5G服务并正在快速扩张。 除了电信运营商之外,企业也对使用 5G 建立私有网络产生了浓厚的兴趣,这些私有网络利用了更高的带宽、更低的延迟…...
vector、list、queue
引用:windows程序员面试指南 vector vector 类似于C语言中的数组 vector 支持随机访问,访问某个元素的时间复杂度 O(1) vector 插入和删除元素效率较低,时间复杂度O(n) vector 是连续存储,没有内存碎片,空间利用率高…...
操作系统面经
进程与线程区别 1.进程是资源分配的最小单位,线程是程序执行的最小单位(资源调度的最小单位) 2.进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数…...
一天约了4个面试,复盘一下面试题和薪资福利
除了最新的面经分享,还有字节大佬的求职面试答疑,告诉你关键问题是什么?少走弯路。**另外本文也汇总了6份大厂面试题:字节、腾讯、小米、腾讯云、滴滴、小米游戏。**希望对大家有帮助。 前言 昨天我的交流群里,有位宝…...
详解单链表(内有精美图示哦)
全文目录引言链表链表的定义与结构链表的分类单链表的实现及对数据的操作单链表的创建与销毁创建销毁单链表的打印单链表的头插与头删头插头删单链表的尾插与尾删尾插尾删单链表的查找单链表在pos位置后插入/删除插入删除单链表在pos位置插入/删除插入删除总结引言 在上一篇文…...
csdn文章导航
这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…...
【Spring】掌握 Spring Validation 数据校验
个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ Spring Validation 数据校验一、什么是 Spring…...
定语 从句
回顾能作定语的成分 形容词:She is a responsible girl.她是一个负责任的姑娘。(前置定语) The girl responsible was expelled.对此负责的姑娘被开除了。(后置定语) 代词:Whose f…...
【数据可视化工具】浅谈 DataEase 和 FineBI 支持的数据源
前言最近对市面上比较火热的数据可视化工具 DataEase 和 FineBI 进行了调研,在支持的数据源方面感觉不太一样,所以就有了这篇文章,话不多说,我们一起来看一下吧!以下的内容,大多来自两个工具的官方文档&…...
100种思维模型之上帝视角思维模型-025
惊奇、愤怒、郁闷,我们觉得生活不精彩,事情乱作一团,但这仅仅是视角问题而已。 换个视角,可以看到不同的世界。 “上帝视角思维模型”,即以一个更高、更客观、更理性的角度来看问题,从而做出理性的决策。 …...
从这5个方面,总结我当PM的第一年
以下5个方面(学习、思考、沟通、执行、产品)的分享,都是我站在巨人的肩膀上,结合自己所学所做总结而来;同时,我也继续学习,不断完善这些知识。如有不当,欢迎大家指正~一、学习&#…...
ChatGPT可以作为一个翻译器吗?
论文地址:https://arxiv.org/abs/2301.08745.pdf 背景 自从OpenAI2022年11月30日发布ChatGPT以来,基本上把NLP所有任务大统一了,那么在机器翻译的表现到底如何呢?腾讯AI Lab在翻译Prompt、多语言翻译以及翻译鲁棒性三方面做了一…...
详述java的设计模式(三)
1.装饰者模式 装饰者模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 使用场景: 在不影响其他对象的情况下ÿ…...
Linux命令·pwd
Linux中用 pwd 命令来查看”当前工作目录“的完整路径。 简单得说,每当你在终端进行操作时,你都会有一个当前工作目录。 在不太确定当前位置时,就会使用pwd来判定当前目录在文件系统内的确切位置。1.命令格式:pwd [选项…...
以图搜图服务快速搭建
以图搜图服务快速搭建 电商公司,管理的商品少则几千,多则上百万。如何帮助用户从多如牛毛的商品中找到类似的商品就成了问题。 以图搜图就可以很好的帮助解决这个问题,通过 Towhee(resnet50 模型) Milvus 如何实现本…...
【TensorFlow安装踩坑记录】
TensorFlow安装踩坑记录第一步,切换服务器cuda版本第二步,conda安装tensorflow记录一下最近安装Tensorflow v1时遇到的问题和解决办法第一步,切换服务器cuda版本 首先我想安装tensorflow 1.13.1,兼容的cuda版本是10.0,…...
沈阳市三好街网站建设公司/seo效果最好的是
曲率半径:曲率的倒数就是曲率半径。曲线的曲率。平面曲线的曲率就是针对曲线上某个点的切线方向角对弧长的转动率,通过微分来定义,表明曲线偏离直线的程度。Klim|Δα/Δs|,Δs趋向于0的时候,定义k就是曲率。曲率半径主…...
wordpress 远程管理/2023引流软件
php 图片局部打马赛克 原理: 对图片中选定区域的每一像素,添加若干宽度及高度,生成矩型。而每一像素的矩型重叠在一起。就形成了马赛克效果。本例使用GD库的imagecolorat获取像素颜色,使用imagefilledrectangle画矩型。效果图&…...
做盗版电影网站吗/南京关键词网站排名
为更好地从Activity跳转,并且带数据传递和关闭Activity,加上请求码与返回码得到数据。请看详细下面的例子。 让我们看一下原代码。虽然,只有代码,大家肯定看效果的。 package com.smart.activity; import android.app.Activity…...
平阳网站制作/百度关键词搜索
自动化测试面试什么是自动化测试自动化测试分为哪几类什么时候会用到自动化测试自动化过程涉及哪些步骤简述你了解的延迟等待的方式如何设计出一个高质量的自动化脚本良好的自动化测试工具的特征是什么简述你知道的自动化测试工具QTPAppiumSeleniumJenkins手动测试的缺点是什么…...
wordpress 联系地图/百度搜索高级搜索技巧
最近博客更新的少了,相对而言,我在自己的个人公众号里还是挺活跃的,大家可以扫描旁边的二维码,或者微信搜索公众号:“编程一生”加关注。 在分布式的年代,一个应用需要部署到多台服务器上。那么要查看日志文…...
网络信息设计/网站的seo是什么意思
介意女朋友学历低吗在最近的精益咖啡回顾中,我们团队的每个成员都被要求提出一个有关工作环境的问题或担忧。 对我来说,我最迫切的问题是我们应该介意其他事务。 在表达了我的担忧之后,我的团队做出了微妙的回应,因为人们对于表达…...