python的多线程和多进程

首先需要明确的是,多进程和其他语言的一样,能够利用多核cpu,但是python由于GIL的存在,多线程在执行的时候,实际上,每一时刻只有一个线程在执行。相当于是单线程。然而多线程在某些情况下,还是能够起到加速的效果。

需要了解的是,程序的耗时一般消耗在IO和CPU上,按照占比不同,一般分为IO密集型或者CPU密集型。比如文件读写、网络传输,磁盘IO等,属于IO密集型,而矩阵计算、数值计算这种就属于CPU密集型。在单线程中,遇见IO操作的时候,CPU会阻塞,直到IO操作完成,花费的时间成本为IO耗时加CPU耗时。但是在多线程中,遇见IO操作的时候,该线程会交出GIL,其他线程可以继续运行,这样可以让CPU和IO并行。因此,如果是IO密集型,即在代码中,主要是进行IO读取,那么多线程仍然能够起到加速左右,值得注意的是,这里的加速效果应该是来自于处理IO的设备,支持并行IO,即同一时刻,能够处理多个IO请求。反之,如果是CPU密集型,IO耗时忽略不计的话,此时多线程相当于是单线程,同时考虑到线程的上下文切换,那么多线程的运行时间反而会更多。

线程池的使用方法submit和map

python中concurrent.futures这个类提供了线程池和进程池的接口。as_completed按照任务的完成时间返回,map按照任务的添加时间返回

我们可以通过submit或map添加任务,但使用起来存在细微差别。

一般通过submit得到一个包含future对象的列表,然后通过concurrent.futures.as_completed去遍历这个列表,该方法会阻塞,可以设置超时时间。每当有任务完成的时候,就能通过future.result()得到任务执行的结果,该方法同样会阻塞,可以设置超时时间。因此通过这种方法,输出是按照任务执行完成的时间排序的。

当然,我们也可以不用as_completed去遍历,这样就按照任务的顺序返回。因为每个任务如果没完成就阻塞,完成了就添加。

import concurrent.futures
import timedef task(times):# 模拟任务执行time.sleep(times)return timesdef main():num_threads = 3with concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) as executor:# 提交任务到线程池# submitfutures = [executor.submit(task, t) for t in [7, 1, 3, 8]]# # 收集每个任务的结果results = []# for future in concurrent.futures.as_completed(futures):#     result = future.result()#     results.append(result)for future in futures:result = future.result()results.append(result)# map# results = []# futures = executor.map(task, [7, 1, 3, 8])# for future in futures:#     results.append(future)print(f"results = {results}")if __name__ == "__main__":main()

上面两种submit,依次输出1 3 7 8和7 1 3 8

map函数则不太一样,第一个参数是需要线程执行的函数,第二个参数是一个迭代器,会依此将参数应用到线程函数中。返回结果和列表的顺序一样。返回7 1 3 8

多线程和多进程的对比

在这里插入图片描述

线程安全

import concurrent.futures
import random
from threading import Lock
import time# 共享变量
shared_variable = 0
# 锁对象,用于保护共享变量的访问
lock = Lock()def task(task_id):global shared_variable# 模拟任务执行# 获取锁,确保对共享变量的访问是线程安全的for _ in range(1000000):with lock:shared_variable += 1# shared_variable += 1def main():num_threads = 2with concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) as executor:# 提交任务到线程池futures = [executor.submit(task, i) for i in range(2)]# 收集每个任务的结果results = []for future in concurrent.futures.as_completed(futures):result = future.result()results.append(result)print(f"results = {results}")print(f"shared_variable = {shared_variable}")if __name__ == "__main__":main()

注释掉上面代码的lock,试试加锁和不加锁,可以很清晰的看到,加锁的时候不会有竞争冒险,而不加锁则可能有竞争冒险。因为几率是比较小的,观察不到的话,可以加大循环的次数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/450312.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go-知识泛型

Go-知识泛型 1. 认识泛型1.1 不使用泛型1.2 使用泛型 2. 泛型的特点2.1 函数泛化2.2 类型泛化 3. 类型约束3.1 类型集合3.2 interface 类型集合3.2.1 内置interface类型集合3.2.2 自定义interface类型集合3.2.2.1 任意类型元素3.2.2.2 近似类型元素3.2.2.3 联合类型元素 3.2.3 …

Windows上安装Go并配置环境变量(图文步骤)

前言 1. 本文主要讲解的是在windows上安装Go语言的环境和配置环境变量; Go语言版本:1.23.2 Windows版本:win11(win10通用) 下载Go环境 下载go环境:Go下载官网链接(https://golang.google.cn/dl/) 等待…

Windows的一些技巧

一、如何去掉桌面程序图标的小箭头 1、使用WIN + R 快捷键调出运行窗口 2、在运行 窗口输入 regedit,打开注册表编辑器 3、在注册表编辑器 中找到 HKEY_CLASSES_ROOT\lnkfile 4、在右侧窗格中找到 IsShortcut 项,右键 删除 二、WIN10如何打开图片查看器 1、使用WIN + R 快…

kali——hping3的使用

目录 前言 ping测试 端口扫描 ​编辑 源IP伪造 修改TTL值 洪水攻击 ​编辑 前言 hping命令行工具主要用于构造和发送自定义的 TCP/IP 数据包。它是一个非常强大的工具,用于网络测试、安全审计和防火墙测试。 ping测试 hping3 -1 目标IP //此命令…

Node.js基础与应用

目录 1.要求 2.创建第一个Node.js代码 2.1 安装 VSCode 和所需插件 2.2 安装 Node.js 和 Yarn 2.3 创建 Node.js 项目 2.3.1 在 VSCode 中打开一个新文件夹 2.3.2 初始化 Node.js 项目 2.3.3 安装 Express 2.4 编写 Node.js 应用 2.4.1 创建主文件 2.4.2 运行应用 …

Golang | Leetcode Golang题解之第475题供暖器

题目&#xff1a; 题解&#xff1a; func findRadius(houses, heaters []int) (ans int) {sort.Ints(houses)sort.Ints(heaters)j : 0for _, house : range houses {dis : abs(house - heaters[j])for j1 < len(heaters) && abs(house-heaters[j]) > abs(house-…

【vue+printJs】前端打印, 自定义字体大小, 自定义样式, 封装共享样式

效果示例 思维导图 目录 1,基本使用1, 依赖下载2, 页面导入3, 修改字体大小(可行但不推荐) 2, 自定义样式,字体大小1, 修改字体大小(推荐)2, 自定义样式3, 封装共享样式 3, 去除页面页脚内容4, 测试案例demo, 直接cv可用5, print-js的其他参数说明 1,基本使用 1, 依赖下载 …

Java 小游戏《超级马里奥》

文章目录 一、效果展示二、代码编写1. 素材准备2. 创建窗口类3. 创建常量类4. 创建动作类5. 创建关卡类6. 创建障碍物类7. 创建马里奥类8. 编写程序入口 一、效果展示 二、代码编写 1. 素材准备 首先创建一个基本的 java 项目&#xff0c;并将本游戏需要用到的图片素材 image…

小马识途海外媒体推广有何优势?

互联网让地球变得像一个村子一样&#xff0c;信息可以瞬间变得人尽皆知&#xff0c;商品和服务也同样习惯了跨国合作。中国不少物美价廉的产品在世界各地都很受欢迎&#xff0c;国内小资群体对国外的服饰和美妆更是偏爱有加。小马识途营销顾问认为&#xff0c;中国品牌不出走国…

“趋势买点”,智能捕捉市场底部的工具指标

“趋势买点”&#xff0c;智能捕捉市场底部的工具指标 分享的这个指标包含副图与主图&#xff0c;不含未来函数&#xff0c;旨在通过分析市场波动找到可靠的买点信号&#xff0c;以便在底部进行抄底操作。 "趋势买点"的副图信号作为判断市场底部的重要依据&#xff0…

只想简单跑个 AI 大模型,却发现并不简单

之前我用 Ollama 在本地跑大语言模型&#xff08;可以参考《AI LLM 利器 Ollama 架构和对话处理流程解析》&#xff09;。这次想再捣鼓点进阶操作&#xff0c;比如 fine-tuning。 我的想法是&#xff1a;既然有现成的大模型&#xff0c;为什么不自己整理些特定领域的数据集&am…

6云图书管理系统-图书展示

1 /src/store中新增userInfo.js&#xff0c;用于保存用户的登录信息 import { defineStore } from "pinia" import { ref } from vueexport const userInfoStore defineStore(userInfo, () > {//1.定义用户信息const info ref({})const isAdmin ref(false)//2…

css 仿微信朋友圈图片自适应九宫格

不好用请移至评论区揍我 原创代码,请勿转载,谢谢! 示例效果 1 ~ 5张图与5 ~ 9张图 代码实现 <view style="

卸载Python

1、查看安装框架位置并删除 Sudo rm -rf /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8 2、查看应用并删除 在 /Applications/Python 3.x 看是否存在&#xff0c;如果存在并删除。 3、删除软连接 ls -l /usr/bin/py* 或 ls -…

什么是分布式锁?Redis的分布式锁又是什么?

什么是分布式锁&#xff1f; 分布式锁是一种用于解决分布式系统中多节点对共享资源并发访问问题的机制。在分布式系统中&#xff0c;多个服务器实例或服务进程可能同时操作某个共享资源&#xff08;如数据库记录、缓存条目、文件等&#xff09;&#xff0c;导致数据不一致或竞…

千鹿 AI:强大的抠图神器,让你的工作效率飙升99%

宝子们&#xff0c;今天一定要给大家分享一款超厉害的抠图工具 —— 千鹿 AI。千鹿 AI 用起来真的是极其方便&#xff0c;仅仅上传一张图片&#xff0c;短短几秒钟的时间&#xff0c;就能够获得一张边缘超级清晰的抠图成品&#xff0c;实在是令人惊叹。 鹿 AI 的厉害之处有很多…

【Linux系统编程】环境基础开发工具使用

目录 1、Linux软件包管理器yum 1.1 什么是软件包 1.2 安装软件 1.3 查看软件包 1.4 卸载软件 2、Linux编辑器-vim 2.1 vim的概念 2.2 vim的基本操作 2.3 vim的配置 3、Linux编译器-gcc/g 3.1 gcc编译的过程​编辑​编辑​编辑 3.2 详解链接 动态链接 静态链接 4…

二百六十九、Kettle——ClickHouse清洗ODS层原始数据增量导入到DWD层表中

一、目的 清洗ClickHouse的ODS层原始数据&#xff0c;增量导入到DWD层表中 二、实施步骤 2.1 newtime select( select create_time from hurys_jw.dwd_statistics order by create_time desc limit 1) as create_time 2.2 替换NULL值 2.3 clickhouse输入 2.4 字段选择 2.5 …

UDP反射放大攻击防范手册

UDP反射放大攻击是一种极具破坏力的恶意攻击手段。 一、UDP反射放大攻击的原理 UDP反射放大攻击主要利用了UDP协议的特性。攻击者会向互联网上大量的开放UDP服务的服务器发送伪造的请求数据包。这些请求数据包的源IP地址被篡改为目标受害者的IP地址。当服务器收到这些请求后&…

『网络游戏』服务器启动逻辑【16】

新建Visual Studio工程命名为NetGameServer 重命名为ServerStart.cs 创建脚本&#xff1a; 编写脚本&#xff1a;ServerRoot.cs 编写脚本&#xff1a;ServerStart.cs 新建文件夹 调整脚本位置 新建文件夹 新建文件夹网络服务 创建脚本&#xff1a;NetSvc.cs 编写脚本&#xff1…