python多线程+异步编程让你的程序运行更快

news2025/4/18 11:28:44

多线程简介

        多线程是Python中实现并发编程的重要方式之一,它允许程序在同一时间内执行多个任务。在某些环境中使用多线程可以加快我们代码的执行速度,例如我们通过爬虫获得了一个图片的url数组,但是如果我们一个一个存储很明显会非常缓慢,如果我们多创建几个线程执行这样我们的代码就会快上若干倍,同时在之前的实验中我们做了一个socket的聊天室如果它是单线程的话,就只能进行一问一答,于是我们创建了两个线程,一个线程用来监听对方的信息,另一个线程用来发送消息。

多线程编程

使用threading库创建线程并使用

接下来使用一个小代码来理解一下线程的概念。

from threading import Thread

def print_name(name):
    for i in range(100):
        print(f'name:{name},num:{i}')

def main():
    t1 = Thread(target=print_name, args=('张三',))
    t2 = Thread(target=print_name, args=('李四',))
    t1.start()
    t2.start()
    t1.join()
    t2.join()

if __name__ == '__main__':
    main()

        在代码中Thread类代表的是线程,我们定义了一个函数print_name作为任务,传入参数name代表名字,我们在函数中使用循环,让名字重复打印100次,同时显示第几次打印。在主函数中创建了两个线程t1和t2,再同时启动它们,join代表等待任务完成。

        在结果中我们发现,输出的张三和李四是掺杂在一起的,于是我们可以想象到它的执行过程应该是这样的:

                                                             t1   

          主进程                   ---------------------------------->

---------------------------->                                                 -------------------------------------->

                                        ---------------------------------->

                                                              t2  

        但是,我们思考一下,即使是输出乱套了,它依然是按照张三……李四……一条一条地执行print语句,输出数据的。而不是输出张李三四……的数据。

        这是因为在计算机中,打印资源为互斥资源,在访问的过程中需要互斥的访问,就是有的进程一旦占用了该资源,就必须等待它结束或者中断释放以后,别的进程才可以使用。

睡眠排序

        睡眠排序作为一种最没用的排序方式,虽然我们在实操的过程中根本就用不到这种方法。但是作为一个小练习,让我们对多线程的理解更加深刻,也是不错的。

from threading import Thread
import time
def act(num):
    time.sleep(num/10)
    print(num)

def main():
    c = [5,4,2,9,8,7,6,1,3]
    for i in range(len(c)):
        t = Thread(target=act,args=(c[i],))
        t.start()
if __name__ == '__main__':    
    main()

        这个代码的思路是,把要排序的数组进行遍历,通过在循环中给每一个数值创建线程再执行。在线程中,规定先睡眠,根据传入的数字的大小决定谁先醒来,这样先醒来的线程就会先输出,所以先输出的就是较小的数。最后数字会按照从小到大的顺序输出。这种思路和传统的排序相比较它会把压力全部给到cpu。

线程池

from concurrent.futures import ThreadPoolExecutor

def func(a):
    for i in range(10):
        print(a)
def main():
    with ThreadPoolExecutor(10) as t:
        t.submit(func,'1')
        t.submit(func,'2')
        t.submit(func,'3')
        t.submit(func,'4')
        t.submit(func,'5')
        t.submit(func,'6')

if __name__ == '__main__':
    main()

        在ThreadPoolExecutor(10)中传入的参数是线程池中可以容纳的最大的线程的数量,这个数值和电脑的核数量有关,在一般情况下,推荐线程数 ≈ CPU核心数 + 1。

        至于电脑的cpu是几核的,可以通过下面的代码查看。

锁🔒

        锁(Lock)是多线程编程中最基本的同步机制,用于解决多线程环境下对共享资源访问的竞争问题,防止数据不一致的情况发生。多个线程同时访问/修改共享数据时,执行结果依赖于线程执行的顺序,如果进程之间有资源竞争的情况,那么就可能会造成资源的混乱。

        例如count+=1和读写文件的操作。

import threading

counter = 0
lock = threading.Lock()

def increment():
    global counter
    for _ in range(100000):
        with lock:
            counter += 1

threads = []
for _ in range(5):
    t = threading.Thread(target=increment)
    threads.append(t)
    t.start()

for t in threads:
    t.join()

print(f"counter: {counter}")

        但是在使用锁的过程中,一定要注意简单的锁不能重复使用,否则会导致进程无法被唤醒造成死锁。

异步编程介绍

        异步编程和多线程编程是现代软件开发中两种主要的并发处理方式,它们各有特点,适用于不同的场景。异步编程核心概念是任务发起后不必等待完成,可以继续执行其他操作,核心调度机制,管理所有异步任务的执行,所有任务在一个线程内交替执行,任务主动让出控制权。

使用async和await关键字

async

用于声明一个函数为异步函数(协程函数),被修饰的函数在被调用时会返回一个协程对象,而不是立即执行。

await

暂停当前协程的执行,等待一个可等待对象完成,非阻塞地等待。

import asyncio

async def fetch_data(n):
    print(f"开始获取数据{n}")
    await asyncio.sleep(2)
    print(f"数据获取完成{n}")

async def main():
    task1 = asyncio.create_task(fetch_data(1))
    task2 = asyncio.create_task(fetch_data(2))
    
    await task1
    await task2

asyncio.run(main())

        它的运行结果是

        在执行完task1的第一个打印后,有一个await关键字,到这里程序会暂时挂起当前的任务转而去执行其它的任务。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

各种场景的ARP攻击描述笔记(超详细)

1、ARP报文限速 上一章我们说过ARP报文也是需要上送CPU进行处理的协议报文,如果设备对收到的大量ARP报文全部进行处理,可能导致CPU负荷过重而无法处理其他业务。因此,在处理之前需要对ARP报文进行限速,以保护CPU资源。 1.根据源MAC地址或源IP地址进行ARP限速 当设备检测到某一…

庙算兵推:使用Streamlit框架构建了一个智能作战推演系统。

这段代码是一个完整的军事模拟应用,使用Streamlit框架构建了一个智能作战推演系统。该系统包括了三维地图显示、作战单位管理、应急事件处理等功能。用户可以通过界面控制推演的开始和暂停,调整时间加速倍率,并查看实时的战斗情况和系统状态。…

HDCP(四)

HDCP驱动开发实战深度解析 以下从协议栈架构、核心模块实现、安全设计到硬件集成,结合HDCP 2.x规范与主流硬件平台(如ARM、FPGA)特性,系统拆解驱动开发关键环节: 1. 协议栈架构与模块划分 驱动分层设计 硬件抽象层&…

Docker MySQL的主从同步 数据备份 数据同步 配置文件

创建主库 docker run \--namemysql_1 \-e MYSQL_ROOT_PASSWORD123456 \-p 3306:3306 \-v mysql_main_data:/var/lib/mysql \--restart unless-stopped \-d \mysql:8.0进入容器内部 docker exec -it mysql_1 bash查找配置文件 find / -name my.cnf复制出主机 docker cp mysql…

996引擎-疑难杂症:Ctrl + F9 编辑好的UI进入游戏查看却是歪的

Ctrl F9 编辑好UI后,进入游戏查看却是歪的。 检查Ctrl F10 是否有做过编辑。可以找到对应界面执行【清空】

JQuery初步学习

文章目录 一、前言二、概述2.1 介绍2.2 安装 三、语法3.1 文档就绪3.2 选择器 四、事件4.1 概述4.2 事件绑定/解绑4.3 一次性事件4.4 事件委托4.5 自定义事件 五、效果5.1 隐藏/显示5.2 淡入淡出5.3 滑动5.4 动画 六、链七、HTML7.1 内容/属性7.2 元素操作7.3 类属性7.4 样式属…

基于 Spring Boot 瑞吉外卖系统开发(三)

基于 Spring Boot 瑞吉外卖系统开发&#xff08;三&#xff09; 分类列表 静态页面 实现功能所需要的接口 定义Mapper接口 Mapper public interface CategoryMapper extends BaseMapper<Category> {}定义Service接口 public interface CategoryService extends ISe…

winserver2022备份

安装备份&#xff0c;然后等待安装完成即可 然后可以在这里看到安装好的win server2022备份 一直下一步然后到这里 不要用本地文件夹备份 备份到远程服务器&#xff0c;远程服务器路径 然后确定备份即可 如何恢复呢&#xff1f; 点击右侧的恢复就可以了 打开任务计划程序 这…

GAT-GRAPH ATTENTION NETWORKS(论文笔记)

CCF等级&#xff1a;A 发布时间&#xff1a;2018年 代码位置 25年4月21日交 目录 一、简介 二、原理 1.注意力系数 2.归一化 3.特征组合与非线性变换 4.多头注意力 4.1特征拼接操作 4.2平均池化操作 三、实验性能 四、结论和未来工作 一、简介 图注意力网络&…

PDFBox/Itext5渲染生成pdf文档

目录 PDFBox最终效果实现代码 Itext5最终效果实现代码 PDFBox 使用PDFBox可以渲染生成pdf文档&#xff0c;并且自定义程度高&#xff0c;只是比较麻烦&#xff0c;pdf的内容位置都需要手动设置x&#xff08;横向&#xff09;和y&#xff08;纵向&#xff09;绝对位置&#xff…

PyTorch Tensor维度变换实战:view/squeeze/expand/repeat全解析

本文从图像数据处理、模型输入适配等实际场景出发&#xff0c;系统讲解PyTorch中view、squeeze、expand和repeat四大维度变换方法。通过代码演示对比不同方法的适用性&#xff0c;助您掌握数据维度调整的核心技巧。 一、基础维度操作方法 1. view&#xff1a;内存连续的形状重…

【NLP 面经 9、逐层分解Transformer】

目录 一、Transformer 整体结构 1.Tranformer的整体结构 2.Transformer的工作流程 二、Transformer的输入 1.单词 Embedding 2.位置 Embedding 计算公式&#xff1a; 三、Self-Attention 自注意力机制 1.Self-Attention 结构 ​编辑 2.Q、K、V的计算 代码实现 3.Self-Attenti…

这是一个文章标题

# Markdown 全语法示例手册本文档将全面演示 Markdown 的语法元素&#xff0c;包含 **标题**、**列表**、**代码块**、**表格**、**数学公式** 等 18 种核心功能。所有示例均附带实际应用场景说明。---## 一、基础文本格式### 1.1 标题层级 markdown # H1 (使用 #) ## H2 (使用…

xtrabackup备份

安装&#xff1a; https://downloads.percona.com/downloads/Percona-XtraBackup-8.0/Percona-XtraBackup-8.0.35-30/binary/tarball/percona-xtrabackup-8.0.35-30-Linux-x86_64.glibc2.17.tar.gz?_gl1*1ud2oby*_gcl_au*MTMyODM4NTk1NS4xNzM3MjUwNjQ2https://downloads.perc…

(51单片机)串口通讯(串口通讯教程)(串口接收发送教程)

前言&#xff1a; 今天有两个项目&#xff0c;分别为&#xff1a; 串口接收: 串口发送&#xff1a; 如上图将文件放在Keli5 中即可&#xff0c;然后烧录在单片机中就行了 烧录软件用的是STC-ISP&#xff0c;不知道怎么安装的可以去看江科大的视频&#xff1a; 【51单片机入门…

redis 延迟双删

Redis延迟双删是一种用于解决缓存与数据库数据一致性问题的策略&#xff0c;通常在高并发场景下使用。以下是其核心内容&#xff1a; 1. 问题背景 当更新数据库时&#xff0c;如果未及时删除或更新缓存&#xff0c;可能导致后续读请求仍从缓存中读取旧数据&#xff0c;造成数…

大语言模型中的幻觉现象深度解析

一、幻觉的定义及出现的原因 1. 基本定义 ​​幻觉(Hallucination)​​ 指大语言模型在自然语言处理过程中产生的与客观事实或既定输入相悖的响应&#xff0c;主要表现为信息失准与逻辑矛盾。 2. 幻觉类型与机制 2.1 事实性幻觉 ​​定义​​&#xff1a;生成内容与可验证…

详解如何从零用 Python复现类似 GPT-4o 的多模态模型

&#x1f9e0; 向所有学习者致敬&#xff01; “学习不是装满一桶水&#xff0c;而是点燃一把火。” —— 叶芝 我的博客主页&#xff1a; https://lizheng.blog.csdn.net &#x1f310; 欢迎点击加入AI人工智能社区&#xff01; &#x1f680; 让我们一起努力&#xff0c;共创…

大模型训练关键两步

大模型的核心原理是基于深度学习&#xff0c;通过多层神经网络进行数据建模和特征提取。目前大部分的大模型采用的是Transformer架构&#xff0c;它采用了自注意力机制&#xff0c;能够处理长距离依赖关系&#xff0c;从而更好地捕捉文本的语义和上下文信息。大模型还结合了预训…

前端面试宝典---创建对象的配置

Object.create 对整个对象的多个属性值进行配置 创建对象 不可更改属性值 // 创建对象 不可更改属性值 let obj Object.create({}, {name: {value: lisi,writable: false,},age: {value: 20,writable: true,} })console.log(初始化obj, obj) obj.name wangwu console.log(…