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

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

多线程简介

        多线程是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关键字,到这里程序会暂时挂起当前的任务转而去执行其它的任务。

相关文章:

  • 蓝桥杯 分解质因数(唯一分解定理)
  • 【专题】贪心算法
  • [C语言]gets和fgets函数区别及详解
  • uniapp微信小程序图片生成水印
  • scrum详细理解
  • 前端笔记-JavaScript部分(上)
  • [特殊字符]深入浅出理解 URL:从新手到精通的系统解析
  • App Cleaner Pro for Mac 中 Mac软件卸载工具
  • 10 个最新 CSS 功能已在所有主流浏览器中得到支持
  • 软件设计师-下午题-试题1(15分)
  • Excel 动态比较两列数据:实现灵活的数据验证
  • minio命令行客户端mc常见用法
  • 活动策划岗位(应届生求职)
  • Java的三大特性详解
  • 蓝桥杯 分巧克力
  • DirectX12(D3D12)基础教程六 计算着色器通用计算
  • T-Box车载系统介绍及其应用
  • 【保姆级图解】插入排序 算法详解:直接插入排序、希尔排序
  • C# js 判断table中tr否存在相同的值
  • 利用 PHP 爬虫获取京东商品详情 API 返回值说明及代码示例
  • 湖北公司响应式网站建设推荐/甘肃省seo关键词优化
  • wordpress自定义文章模板插件/北京百度推广排名优化
  • 陕西交通建设集团公司网站/谷歌浏览器下载手机版
  • 龙华网站建设销售员/网络推广费用
  • 建设行政主管部门政务网站/深圳网络公司推广平台
  • 酒店 网站建设 中企动力/关键词优化推广公司