python多线程与多进程
多线程与多进程
一, 什么是进程, 什么是线程?
进程: 运行中的程序. 每次我们执行一个程序, 咱们的操作系统对自动的为这个程序准备一些必要的资源(例如, 分配内存, 创建一个能够执行的线程. )
线程: 程序内, 可以直接被CPU调度的执行过程. 是操作系统能够进行运算调度的最小单位. 它被包含在进程之中, 是进程中的实际运作单位.
进程与线程之间的关系:
进程是资源单位. 线程是执行单位. 就好比是一家公司. 一家公司的资源就是桌椅板凳, 电脑饮水机这些资源, 但是, 我们如果说一家公司正在运转着, 运行着. 那里面必须要有能为这家公司工作的人. 程序里面也一样, 进程就是为了程序运行而需要的各种资源. 但是程序想要运行, 就必须由线程来被CPU调度执行.
我们运行的每一个程序默认都会有一个线程. 哪怕是只有helloworld级别的程序. 想要执行. 也会有一个线程产生.
二, 多线程
顾名思义, 多线程就是让程序产生多个线程一起去执行. 还拿公司举例子. 一家公司里如果只有一个员工, 工作效率肯定不会高到哪里去. 怎么提高效率? 多招点儿人就OK了.
如何实现多线程, 在python中, 有两种方案实现多线程.
1. 直接用Thread创建线程
我们先看看单线程的效果
def func():for i in range(1000):print("func", i)if __name__ == '__main__':func()for i in range(1000):print("main", i)
再看多线程
from threading import Threaddef func():for i in range(1000):print("func", i)if __name__ == '__main__':t = Thread(target=func)t.start()for i in range(1000):print("main", i)
2. 继承Thread类
from threading import Threadclass MyThread(Thread):def run(self):for i in range(1000):print("func", i)if __name__ == '__main__':t = MyThread()t.start()for i in range(1000):print("main", i)
以上两种是最基本的python创建多线程的方案. python还提供了线程池
3. 线程池
python还提供了线程池功能. 可以一次性的创建多个线程, 并且, 不需要我们程序员手动去维护. 一切都交给线程池来自动管理.
# 线程池
def fn(name):for i in range(1000):print(name, i)if __name__ == '__main__':with ThreadPoolExecutor(10) as t:for i in range(100):t.submit(fn, name=f"线程{i}")
如果任务有返回值怎么办?
def func(name):time.sleep(2)return namedef do_callback(res):print(res.result())if __name__ == '__main__':with ThreadPoolExecutor(10) as t:names = ["线程1", "线程2", "线程3"]for name in names:# 方案一, 添加回调t.submit(func, name).add_done_callback(do_callback)if __name__ == '__main__':start = time.time()with ThreadPoolExecutor(10) as t:names = [5, 2, 3]# 方案二, 直接用map进行任务分发. 最后统一返回结果results = t.map(func, names, ) # 结果是按照你传递的顺序来执行的, 代价就是如果第一个没结束. 后面就都没结果for r in results:print("result", r)print(time.time() - start)
4. 多线程在爬虫中的应用
http://www.xinfadi.com.cn/marketanalysis/0/list/1.shtml
依然用新发地这个案例.
import requests
from lxml import etree
from concurrent.futures import ThreadPoolExecutordef get_page_source(url):resp = requests.get(url)return resp.textdef get_totle_count():url = "http://www.xinfadi.com.cn/marketanalysis/0/list/1.shtml"source = get_page_source(url)tree = etree.HTML(source)last_href = tree.xpath("//div[@class='manu']/a[last()]/@href")[0]totle = last_href.split("/")[-1].split(".")[0]return int(totle)def download_content(url):source = get_page_source(url)tree = etree.HTML(source)trs = tree.xpath("//table[@class='hq_table']/tr[position() > 1]")result = []for tr in trs:tds = tr.xpath("./td/text()")result.append((tds[0], tds[1], tds[2], tds[3], tds[4], tds[5], tds[6]))return resultdef main():f = open("data.csv", mode="w")totle = get_totle_count()url_tpl = "http://www.xinfadi.com.cn/marketanalysis/0/list/{}.shtml"with ThreadPoolExecutor(50) as t:data = t.map(download_content, (url_tpl.format(i) for i in range(1, totle+1)))# 拿到所有任务的返回for item in data:# 每个任务的数据循环出一行for detial in item:# 写入文件content = ",".join(detial) + "\n"print(content)f.write(content)if __name__ == '__main__':main()
三, 多进程
一个公司能创造的价值毕竟是有限的. 怎么办? 开分公司啊. 此所谓多进程. python实现多进程的方案和多线程几乎一样. 非常的简单
###1. 直接用Process创建进程
def func():for i in range(1000):print("func", i)if __name__ == '__main__':p = Process(target=func)p.start()for i in range(1000):print("main", i)
2. 继承Process类
class MyProcess(Process):def run(self):for i in range(1000):print("MyProcess", i)if __name__ == '__main__':t = MyProcess()t.start()for i in range(1000):print("main", i)
###3.多进程在爬虫中的应用
我们一般很少直接使用多进程. 最适合使用多进程的情况是: 多个任务需要一起执行. 并且互相之间数据可能有交汇但功能相对独立.比如, 我们自己做一个代理IP池, 就需要从网络上进行抓取, 抓取得到的IP要进行校验才可以进行使用. 此时, 抓取任务和校验任务就相当于完全独立的两个功能. 此时就可以启动多个进程来实现. 再比如, 如果遇到图片抓取的时候, 我们知道图片在一般都在网页的img标签中src属性存放的是图片的下载地址. 此时我们可以采用多进程的方案来实现, 一个负责疯狂扫图片下载地址. 另一个进程只负责下载图片.
综上, 多个任务需要并行执行, 但是任务之间相对独立(不一定完全独立). 可以考虑用多进程.
# 进程1. 从图片网站中提取到图片的下载路径
def get_pic_src(q):print("start main page spider")url = "http://www.591mm.com/mntt/"resp = requests.get(url)tree = etree.HTML(resp.text)child_hrefs = tree.xpath("//div[@class='MeinvTuPianBox']/ul/li/a/@href")print("get hrefs from main page", child_hrefs)for href in child_hrefs:href = parse.urljoin(url, href)print("handle href", href)resp_child = requests.get(href)tree = etree.HTML(resp_child.text)pic_src = tree.xpath("//div[@id='picBody']//img/@src")[0]print(f"put {pic_src} to the queue")q.put(pic_src)# 作业, 分页图片抓取# print("ready to another!")# others = tree.xpath('//ul[@class="articleV2Page"]')# if others:# 进程2. 从图片网站中提取到图片的下载路径
def download(url):print("start download", url)name = url.split("/")[-1]resp = requests.get(url)with open(name, mode="wb") as f:f.write(resp.content)resp.close()print("downloaded", url)def start_download(q):with ThreadPoolExecutor(20) as t:while True:t.submit(download, q.get()) # 启动def main():q = Queue()p1 = Process(target=start_download, args=(q,))p2 = Process(target=get_pic_src, args=(q,))p1.start()p2.start()if __name__ == '__main__':main()相关文章:
python多线程与多进程
多线程与多进程 一, 什么是进程, 什么是线程? 进程: 运行中的程序. 每次我们执行一个程序, 咱们的操作系统对自动的为这个程序准备一些必要的资源(例如, 分配内存, 创建一个能够执行的线程. ) 线程: 程序内, 可以直接被CPU调度的执行过程. 是操作系统能够进行运算调度…...
62从零开始学Java之时间相关的类都有哪些?
作者:孙玉昌,昵称【一一哥】,另外【壹壹哥】也是我哦 千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 我们在开发时,除了数字、数学这样的常用API之外,还有日期时间类,更…...
【Leetcode】买卖股票系列
121. 买卖股票的最佳时机 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔…...
SLAM面试笔记(8) — 计算机视觉面试题
目录 问题1:目标检测的算法分类 问题2:卷积神经网络的组成 问题3:输入层的作用 问题4:卷积层作用 问题5:卷积核类型 问题6:11卷积核作用 问题7:卷积核是否越大越好 问题8:棋…...
聊聊MySQL面试常问名词回表、索引覆盖,最左匹配
文章目录 1. 前言2. 回表操作 Index Lookup2.1 什么是回表2.2 回表的成本2.3 如何避免回表 3. 索引覆盖 Covering Index3.1 什么是索引覆盖3.2 索引覆盖的优点3.3 如何使用索引覆盖 4. 最左匹配原则(Leftmost Prefix Match)4.1 什么是最左匹配原则4.2 最…...
【面试】C/C++面试八股
C/C面试八股 编译过程的四个阶段C和C语言的区别简单介绍一下三大特性多态的实现原理虚函数的构成原理虚函数的调用原理虚表指针在什么地方进行初始化的?构造函数为什么不能是虚函数为什么建议将析构函数设为虚函数虚函数和纯虚函数的区别抽象类类对象的对象模型内存…...
学习记忆——数学篇——算术——无理数
谐音记忆法 2 \sqrt{2} 2 ≈1.41421:意思意思而已;意思意思; 3 \sqrt{3} 3 ≈1.7320:—起生鹅蛋;一起生儿; 5 \sqrt{5} 5 ≈2.2360679:两鹅生六蛋(送)六妻舅;儿儿生…...
python协程和任务
协程概念引入 协程是我要重点去讲解的一个知识点. 它能够更加高效的利用CPU. 其实, 我们能够高效的利用多线程来完成爬虫其实已经很6了. 但是, 从某种角度讲, 线程的执行效率真的就无敌了么? 我们真的充分的利用CPU资源了么? 非也~ 比如, 我们来看下面这个例子. 我们…...
visual studio code配置anaconda3的python虚拟环境
参考: Visual Studio Code配置anconda3虚拟环境 - 知乎...
【Unity3D编辑器开发】Unity3D编辑器开发基础性框架结构【全面总结】
推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 嗨,大家好,我是恬静的小魔龙。 同学们…...
一座“城池”:泡泡玛特主题乐园背后,IP梦想照亮现实
“更适合中国宝宝体质”的主题乐园,被泡泡玛特造出来了。 9月26日,位于北京朝阳公园内的国内首个潮玩行业沉浸式 IP 主题乐园,也是泡泡玛特首个线下乐园——泡泡玛特城市乐园 POP LAND正式开园。 约4万平方米的空间中,泡泡玛特使…...
【什么是闭包? 闭包产生的原因? 闭包有哪些表现形式?】
JS闭包 什么是闭包?闭包产生的原因?闭包有哪些表现形式? 什么是闭包? 闭包是指一个函数可以访问并操作在其作用域之外的变量的能力。在 JavaScript 中,每当函数被创建时,就会创建一个闭包。 以下是一个简单的闭包示例…...
JackJson和FastJson
前言: fastjson是一款强大的json格式转换工具,我个人在开发中就非常喜欢用fastjson;但是由于某些原因,导致fastjson会有一些漏洞,因此在漏洞扫描后需要修复都是要求我们升级版本,或者替换为jackjson&#…...
SpringCloud学习一
单体应用存在的问题 随着业务的发展,开发变得越来越复杂。 修改、新增某个功能,需要对整个系统进行测试、重新部署。 一个模块出现问题,很可能导致整个系统崩溃。 多个开发团队同时对数据进行管理,容易产生安全漏洞。 各个模块…...
SpringBoot, EventListener事件监听的使用
1、背景 在开发工作中,会遇到一种场景,做完某一件事情以后,需要广播一些消息或者通知,告诉其他的模块进行一些事件处理,一般来说,可以一个一个发送请求去通知,但是有一种更好的方式,…...
课题学习(三)----倾角和方位角的动态测量方法(基于陀螺仪的测量系统)
一、内容介绍 该测量系统基于三轴加速度和三轴陀螺仪,安装在钻柱内部,随钻柱一起旋转,形成捷联惯性导航系统,安装如下图所示: 假设三轴加速度和陀螺仪的输出为: f b [ f x f y f z ] T f^b\begin{bmatrix}f_{x} …...
1876. 长度为三且各字符不同的子字符串
1876. 长度为三且各字符不同的子字符串 C代码:滑动窗口 // 存在三种字符,且不重复、子串数量 int countGoodSubstrings(char * s){int k 3;int hash[26] {0};int len 0;int l 0;int ans 0;for (int i 0; i < strlen(s); i) {hash[s[i] - a];if…...
Mall脚手架总结(一)——SpringSecurity实现鉴权认证
前言 在结束理论知识的学习后,荔枝开始项目学习,这个系列文章将围绕荔枝学习mall项目过程中总结的知识点来梳理。本篇文章主要涉及如何整合Spring Security和JWT实现鉴权认证的功能!希望能帮助到一起学习mall项目的小伙伴~~~ 文章目录 前言 …...
beego-简单项目写法--路径已经放进去了
Beego案例-新闻发布系统 1.注册 后台代码和昨天案例代码一致。,所以这里面只写一个注册的业务流程图。 **业务流程图 ** 2.登陆 业务流程图 登陆和注册业务和我们昨天登陆和注册基本一样,所以就不再重复写这个代码 但是我们遇到的问题是如何做代码的迁移&…...
作业本耐用度差距巨大?深圳大明印刷厂拆解合规工艺,告别定制作业本掉页开裂通病
在校园日常教学中,很多学校都会遇到同一个难题:同一学期采购的作业本、定制作业本,品质差距悬殊,有的完好无损用到期末,有的短短几周就出现书脊开裂、页面脱落、边角破损、翻页卡顿等问题。不少人误以为是学生使用习惯…...
【CP-05】RTE运行时环境 - SWC的操作系统接口
CP-05_RTE运行时环境【CP-05】RTE运行时环境 - SWC的“操作系统接口”前言在AUTOSAR架构中,RTE(Runtime Environment,运行时环境)是一个常被提及却难以理解的概念。它像是应用层软件组件(SW-C)与底层基础软…...
告别道路预测老套路:用ParkPredict+模型思路,解决停车场里的‘鬼探头’难题
破解泊车场景预测困局:ParkPredict模型的技术革新与实践停车场里的每一次转向、倒车和避让,都是对自动驾驶系统预测能力的极限挑战。与开放道路的规则明确不同,这里没有清晰的车道线指引,没有统一的行驶方向,只有随时可…...
2026论文降AI怎么挑?亲测好用工具附免费降AI指南
“您的论文AIGC率为42%,超出学校30%的合格线,请修改后重新提交。”赶毕业论文的同学这段时间估计没少收到这样的提醒。2026年知网、万方、维普等主流平台的AI检测算法持续迭代,把AI生成内容改到符合学校要求,已经成了毕业生的刚需…...
翻译 GDB 官方文档
翻译 GDB 官方文档项目地址官方文档地址下载源码包编译html运行翻译程序项目地址 https://github.com/shootercheng/gdb-translate.git 项目结构 $ tree -L 1 . ├── cmd ├── go.mod ├── input ├── internal ├── LICENSE ├── output ├── README.md ├─…...
yuzu模拟器完整指南:在电脑上畅玩Switch游戏的终极解决方案
yuzu模拟器完整指南:在电脑上畅玩Switch游戏的终极解决方案 【免费下载链接】yuzu 任天堂 Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/yu/yuzu 想在电脑上体验任天堂Switch游戏的魅力吗?yuzu模拟器正是你寻找的完美答案。作为…...
基于Max78000与规则引导的音频数据集构建:边缘AI声音识别实战
1. 项目概述:当边缘AI遇见棕榈树里的“窃听者”在边缘计算和物联网设备大行其道的今天,我们常常面临一个核心矛盾:一方面,我们希望设备足够“聪明”,能实时识别并响应特定的声音模式,比如工厂里高压阀门的异…...
Metabase:零代码 BI 数据可视化工具,自建数据看板
Metabase:零代码 BI 数据可视化工具,自建数据看板 在数据驱动决策的时代,能快速看到业务数据的变化趋势至关重要。然而,专业 BI 工具(如 Tableau、Power BI)价格昂贵,而让每个业务同学都学 SQL …...
观察不同模型在统一 API 下的响应速度与输出风格差异
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 观察不同模型在统一 API 下的响应速度与输出风格差异 在为大语言模型应用选择模型时,开发者通常会关注两个核心维度&am…...
让B站缓存视频重获自由:一个简单实用的格式转换工具
让B站缓存视频重获自由:一个简单实用的格式转换工具 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 还记得那个周末的下午吗…...
