当前位置: 首页 > news >正文

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之外,还有日期时间类,更…...

2023年山东安全员c证考试题库及答案解析来了!

...

【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:两鹅生六蛋(送)六妻舅;儿儿生&#xf…...

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 中,每当函数被创建时,就会创建一个闭包。 以下是一个简单的闭包示例&#xf…...

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代码&#xff1a;滑动窗口 // 存在三种字符&#xff0c;且不重复、子串数量 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实现鉴权认证

前言 在结束理论知识的学习后&#xff0c;荔枝开始项目学习&#xff0c;这个系列文章将围绕荔枝学习mall项目过程中总结的知识点来梳理。本篇文章主要涉及如何整合Spring Security和JWT实现鉴权认证的功能&#xff01;希望能帮助到一起学习mall项目的小伙伴~~~ 文章目录 前言 …...

beego-简单项目写法--路径已经放进去了

Beego案例-新闻发布系统 1.注册 后台代码和昨天案例代码一致。,所以这里面只写一个注册的业务流程图。 **业务流程图 ** 2.登陆 业务流程图 登陆和注册业务和我们昨天登陆和注册基本一样&#xff0c;所以就不再重复写这个代码 但是我们遇到的问题是如何做代码的迁移&…...

3种高效方案:让Windows直接运行Android应用的全新体验手册

3种高效方案&#xff1a;让Windows直接运行Android应用的全新体验手册 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 想象一下这样的场景&#xff1a;您需要在电脑上快…...

别再被Linux的free命令骗了!手把手教你读懂‘可用内存’和‘实际空闲内存’的区别

别再被Linux的free命令骗了&#xff01;手把手教你读懂‘可用内存’和‘实际空闲内存’的区别 刚接触Linux服务器管理时&#xff0c;看到free -m输出里那个触目惊心的"free"数值&#xff0c;我的第一反应是&#xff1a;"天哪&#xff0c;内存快用完了&#xff0…...

VS2019编译OpenSceneGraph 3.6.5踩坑全记录:从CMake配置到解决第三方库缺失

VS2019编译OpenSceneGraph 3.6.5实战避坑指南 第一次在Windows平台用VS2019编译OpenSceneGraph 3.6.5时&#xff0c;我原以为按照官方文档就能轻松搞定。直到CMake报出一连串第三方库缺失的红色警告&#xff0c;才意识到这趟编译之旅远没有想象中简单。如果你也正对着Could NOT…...

3个步骤让你在Windows上轻松安装安卓应用:APK安装器完全指南

3个步骤让你在Windows上轻松安装安卓应用&#xff1a;APK安装器完全指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾经想过&#xff0c;如果能在Windows电…...

5个高效方法:如何用AKShare处理金融数据去重,避免重复数据干扰分析

5个高效方法&#xff1a;如何用AKShare处理金融数据去重&#xff0c;避免重复数据干扰分析 【免费下载链接】akshare AKShare is an elegant and simple financial data interface library for Python, built for human beings! 开源财经数据接口库 项目地址: https://gitcod…...

从数据提取到AI记忆:WeChatMsg项目开发者协作实战蓝图

从数据提取到AI记忆&#xff1a;WeChatMsg项目开发者协作实战蓝图 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeCha…...

保姆级教程:STM32F407驱动AD9926并行ADC,从硬件连线到DMA数据搬运全流程

STM32F407实战&#xff1a;AD9926并行ADC驱动与DMA高效数据采集全解析 在工业自动化与精密测量领域&#xff0c;高速数据采集系统的设计一直是嵌入式开发的难点之一。AD9926作为一款12位并行输出ADC芯片&#xff0c;配合STM32F407强大的DCMI接口和DMA控制器&#xff0c;能够构…...

机器学习在芯片电容提取中的应用与挑战

1. 电容提取的技术挑战与机器学习机遇在芯片设计流程中&#xff0c;电容提取是决定最终产品性能的关键环节。当设计进入物理实现阶段&#xff0c;工程师需要精确计算互连结构中导体间的寄生电容&#xff0c;这些数据直接影响时序收敛和功耗分析。传统基于数值求解器的方法&…...

如何快速清理Windows右键菜单:ContextMenuManager的完整使用指南

如何快速清理Windows右键菜单&#xff1a;ContextMenuManager的完整使用指南 【免费下载链接】ContextMenuManager &#x1f5b1;️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager 还在为Windows右键菜单的混乱不堪而…...

从新手到老手:四类Ozon卖家选品工具选择指南

选品工具没有“最好”&#xff0c;只有“最匹配你当前阶段”。四类卖家&#xff0c;四种方案。市面上的Ozon选品工具&#xff0c;功能各有侧重。有的擅长给数据&#xff0c;有的擅长给结论&#xff0c;有的擅长管店铺。不同阶段的卖家&#xff0c;痛点不同&#xff0c;适合的工…...