【python】多任务编程

python多任务编程

有哪些编程提速的方法
单线程串行:不加改造的程序
多线程并发:利用CPU和IO可以同时执行的原理,让CPU不会干巴巴等待IO完成
多CPU并行/多进程:利用多核CPU的能力,真正的并行执行任务
多机器并行:hadoop/hive/spark
异步IO:asyncio:在单线程利用cpu和IO同时执行的原理,实现函数异步执行

使用Lock对资源加锁,防止冲突访问
使用Queue实现不同线程/进程之间的数据通信,实现生产者-消费者模式
使用线程池Pool/进程池Pool,简化线程/进程的任务提交、等待结束、获取结果
使用subprocess启动外部程序的进程,并进行输入输出交互

python并发编程

  • 多线程
  • 多进程
  • 多协程

CPU密集型计算/IO密集型计算

  • **cpu密集型计算:**也叫计算密集型,是指I/O在很短的时间就可以完成,CPU需要大量的计算和处理,特点是CPU占用率非常高
    例如:压缩解压缩、加密解密、正则表达式搜索
  • IO密集型:系统运作大部分的状况是CPU在等I/O的读/写操作,CPU占用率仍然较低
    例如:文件处理程序、网络爬虫程序、读写数据库程序

多线程、多进程、多协程对比

一个进程中可以启动N个线程
多进程 Process:
优点:可以利用多核CPU进行运算
缺点:占用资源多、可启动数目比线程少
适用于:CPU密集型计算

多线程 Thread:
优点:相比进程,更轻量级、占用资源小
缺点:相比进程:多线程只能并发执行,不能利用多CPU(GIL)
相比协程:启动数据有限制,占用内存资源,有线程切换开销
适用于:IO密集型计算、同时运行的任务数目要求不多

一个线程中可以启动N个协程

多协程 Coroutine:
优点:内存开销最少,启动协程数量最多
缺点:支持的库有限制,代码实现复杂
适用于:IO密集型计算、需要超多任务运行、但有现有库支持的场景

python速度慢的两大原因:

相比于C/C++/JAVA,python确实慢,在一些特殊场景下,python比C++慢100~200倍
1、动态类型语言 边解释边执行
2、GIL 无法利用多核CPU并发执行

GIL是什么?

全局解释器锁:是计算机程序设计语言解释器用于同步线程的一种机制,他使得任何时刻仅有一个线程在执行
即便在多核心处理器上,使用GIL的解释器也只允许同一时间执行一个线程

为什么有GIL这个东西?

为了解决多线程之间数据完整性和状态同步问题

怎样规避GIL带来的限制?

1、多线程机制仍然是有用的,用于I/O密集型计算
因为在I/O期间,线程会释放GIL,实现CPU和IO的并行。因此多线程用于IO密集型计算仍可以大幅度提升速度
但是多线程用于CPU密集型计算时,只会更加拖慢速度

2、使用multiprocessing的多进程制实现并行计算、利用多核CPU优势
对了应对GIL,python提供提供了multiprocessing

线程安全概念介绍

线程安全是指某个函数、函数库在多线程环境中被调用时,能够正确地处理多个线程之间的共享变量,使程序功能能正确完成
由于线程的执行随时会发生切换,就造成了不可预料的结果,出现线程不安全

Lock用于解决线程安全问题

 用法一:try-finally模式: 
 import threading 
 lock = threading.Lock()
 lock.acquire() 
 try:

     # do something 
finally:
      lock.release()
 

用法二:with模式
import threading l
lock = threading.Lock() 
with lock:
      # do something

python好用的线程池ThreadPoolExecutor

在这里插入图片描述

使用线程池的好处

1、提升性能:因为减去了大量新建、终止线程的开销,重用了线程资源
2、使用场景:适合处理突发性大量请求或需要大量线程完成任务、但实际任务处理时间较短
3、防御功能:能有效避免系统因为创建线程过多,而导致系统负荷过大相应变慢等问题
4、代码优势:使用线程池的语法比自己新建线程执行线程更加整洁

ThreadPoolExecutor的使用语法

from concurrent.futures import ThreadPoolExecutor,as_completed
# 用法一:map函数很简单,注意map的结果和入参是顺序对应的
with ThreadPoolExecutor() as pool:
     results = pool.map(craw,urls)

     for result in results:
          print(result)

 # 用法二:future模式,更强大  注意如果用as_completed顺序是不定的
with ThreadPoolExecutor as pool:

     futures = [pool.submit(craw,url) for url in urls]  

     for future in futures:
          print(future.result())
     for future in as_completed(futures):
          print(future.result())     

python使用线程在web服务中实现加速

1、web服务的架构以及特点

Web后台服务的特点:
1、web服务对相应时间要求非常高,不如要求200MS返回
2、web服务有大量的依赖IO操作的调用,比如磁盘文件、数据库、远程API

2、使用线程池ThreadPoolExecutor加速

使用线程池ThreadPoolExcutor的好处:
1、方便的将磁盘文件、数据库、远程API的IO调用并发执行
2、线程池的线程数目不会无线创建(导致系统挂掉),具有防御功能

import flask
import json
import time
from concurrent.futures import ThreadPoolExecutor

app = flask.Flask(__name__)
pool = ThreadPoolExecutor()


def read_file():
    time.sleep(0.1)
    return "file_result"

def read_db():
    time.sleep(0.2)
    return "read db"

def read_api():
    time.sleep(0.3)
    return "read api"

@app_route("/")
def index():
    result_file = pool.submit(read_file)
    result_db = pool.submit(read_db)
    result_api = pool.submit(read_api)

    return json.dumps({
        "result_file":result_file.result(),
        "result_db": result_db.result(),
        "result_api": result_api.result()
    })


if __name__ == '__main__':
    app.run()

python进程(适用于CPU密集型)

在这里插入图片描述

python协程:在单线程内实现并发

核心原理:用一个超级循环(其实就是while true)循环;配合IO多路复用原理(IO时可以去干其他事情)

python异步IO库:asyncio

import asyncio
# 获取时间循环
loop = asyncio.get_event_loop()

# 定义协程
async def myfunc(url):
     await get_url(url)

# 创建task列表
tasks = [loop.create_task(my_func(url)) for url in urls]

# 执行爬虫时间列表
loop.run_until_complete(asyncio.wait(tasks))


注意:
需要在异步IO变成中
以来的库必须支持异步IO特征

爬虫引用中:requests 不支持异步  需要用aiohttp


在异步IO中使用信号量控制爬虫并发度

import asyncio
import aiohttp

urls = [
    "https://www.cnblogs.com/#p{page}".format(page=page)
    for page in range(1,50+1)
]

# 进行初始化一个并发量
semaphore = asyncio.Semaphore(10)

async def async_craw(url):
    # 设置并发量
    async with semaphore:
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as resp:
                result = await resp.text()
                print(f"craw url:{url}".format(url=url),{len(result)})



loop = asyncio.get_event_loop()

# 创建task列表
tasks = [loop.create_task(async_craw(url)) for url in urls]





import time
start = time.time()
loop.run_until_complete(asyncio.wait(tasks))
end = time.time()
print("use time second:" ,end - start)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

快速学习Java Agent

1.1 java agent原理 我们知道,要使用Skywalking去监控服务,需要在其 VM 参数中添加 “- javaagent:/usr/local/skywalking/apache-skywalking-apm-bin/agent/skywalking-agent.jar"。这里就 使用到了java agent技术。 Java agent 是什么&#xff…

python tkiinter中滑块的使用

需求:需要在Canvas组件上添加滑块功能 解决:使用tkinter提供的Scrollbar组件,由于没发现直接在画布上显示滑块功能的方法,所以后面采用在显示画布的容器上显示滑块,并绑定到画布上。 具体案例demo: from t…

视频滤波驱动器电路D1671 D1675的性能描述和分析

D1671四阶标清视频滤波器驱动,1CH,工作电压2.8V~5.5V,转换速率40V/s D1675六阶高清视频滤波器驱动,1CH,工作电压2.5V~5.5V,转换速率400V/s

02鸿蒙APP真机运行及证书签名打包

目录 1、真机运行1.1、运行安装错误1.2、解决方案:第一步:安装兼容真机的sdk版本2.2.0(API6),如下图所示:第二步:新建一个API6的工程项目第三步:运行API6创建的工程项目第四步&#…

如何提高嵌入式软件工程师的技术深度?

今日话题,如何提高嵌入式软件工程师的技术深度?建立坚实的基础知识是深入研究的关键。只有深入理解基础知识,才能在理论指导下不断深化和扩展自己的技术。没有坚实的基础,深入研究就显得空中楼阁。如果你有兴趣进入嵌入式行业我可…

数据库——安全性

智能2112杨阳 一、目的与要求: 1、设计用户子模式 2、根据实际需要创建用户角色及用户,并授权 3、针对不同级别的用户定义不同的视图,以保证系统的安全性 二、内容: 先创建四类用户角色: 管理员角色Cusm、客户角…

初级数据结构(三)——栈

文中代码源文件已上传&#xff1a;数据结构源码 <-上一篇 初级数据结构&#xff08;二&#xff09;——链表 | 初级数据结构&#xff08;四&#xff09;——队列 下一篇-> 1、栈的特性 1.1、函数栈帧简述 即使是刚入门几天的小白&#xff0c;对栈这个字…

Linux——MySQL数据库系统()

一、访问MySQL数据库 MySQL数据库系统也是一个典型的C/S(客户端/服务器&#xff09;架构的应用&#xff0c;要访问MySQL数据库需要使用专门的客户端软件。在Linux系统中&#xff0c;最简单、易用的MySQL客户端软件是其自带的mysql命令工具。 1、登录到MySQL服务器经过安装后的初…

深入理解TheadLocal的使用场景和注意事项

前言 在日常实际开发当中我们往往会看到项目中有使用 ThreadLocal 的场景&#xff0c;大多数人有时候可能涉及不到自己的业务则没有进行关注。通常我在看代码时对于一些未知的东西常常引起我的好奇&#xff0c;我往往会分析&#xff1a;为什么要这么做&#xff1f;好处是什么&…

一文看懂支付前链路流程

一文看懂支付前链路流程 前序 首先支付流程讲究的就是快&#xff0c;还有就是订单的冲入&#xff0c;我们不能说一笔交易订单进来都加一个分布式锁去解决&#xff0c;所以我们目前常用的做法就是一个订单进来&#xff0c;首先落库&#xff0c;如果落库失败&#xff0c;并且是…

用XAMPP在Windows系统构建一个本地Web服务器

用XAMPP在Windows系统构建一个本地Web服务器 Build a Local Web Server for Windows with XAMPP By JacksonML 本文简要介绍如何获取和安装XAMPP以实现Windows环境下本地Web服务器的过程&#xff0c;希望对广大网友和学生有所帮助。 所谓本地Web服务器&#xff0c;即使用本地…

UML-认识6种箭头(画类图无烦恼)

文章目录 一、背景二、箭头详解2.1 泛化&#xff08;Generalization&#xff09;2.2 实现&#xff08;Realize&#xff09;2.3 依赖&#xff08;Dependency&#xff09;2.4 关联&#xff08;Association&#xff09;2.5 聚合&#xff08;Aggregation&#xff09;2.6 组合&#…

24V降12V2A同步降压芯片WT6023A

24V降12V2A同步降压芯片WT6023A 今天给大家带来一款高性能的DC/DC转换器WT6023A&#xff0c;快来一起了解一下吧&#xff01; WT6023A是一款采用抖动频率模式控制架构的高效、单片同步降压型DC/DC转换器&#xff0c;能够提供高达6A的连续负载&#xff0c;具有出色的线路和负载…

BugKu-Web-Flask_FileUpload(模板注入与文件上传)

Flask Flask是一个使用Python编写的轻量级Web应用框架。它是一个微型框架&#xff0c;因为它的核心非常简单&#xff0c;但可以通过扩展来增加其他功能。Flask的核心组件包括Werkzeug&#xff0c;一个WSGI工具箱&#xff0c;以及Jinja2&#xff0c;一个模板引擎。 Flask使用BSD…

快速准确翻译文件夹名:英文翻译成中文,文件夹批量重命名的技巧

在处理大量文件夹时&#xff0c;可能会遇到要将英文文件夹名翻译成中文的情况。同时也可能要批量重命名这些文件夹。今天一起来看下云炫文件管理器如何快速准确翻译文件夹名&#xff0c;进行批量重命名的技巧。 下图是文件夹名翻译前后的效果图。 英文文件夹名批量翻译成中文…

注意力机制和自注意力机制

有很多自己的理解&#xff0c;仅供参考 Attention注意力机制 对于一张图片&#xff0c;我们第一眼看上去&#xff0c;眼睛会首先注意到一些重点的区域&#xff0c;因为这些区域可能包含更多或更重要的信息&#xff0c;这就是注意力机制&#xff0c;我们会把我们的焦点聚焦在比…

2023年12月7日:QT实现登陆界面

#include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {//窗口设置this->resize(600,500);//重新设置窗口大小this->setWindowTitle("QQ-盗版");//设置窗口名为QQ-盗版this->setWindowIcon(QIcon("D:\\Qt\\funny\\pi…

【改进YOLOv8】融合感受野注意力卷积RFCBAMConv的杂草分割系统

1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义 随着计算机视觉技术的不断发展&#xff0c;图像分割成为了一个重要的研究领域。图像分割可以将图像中的不同对象或区域进行有效的分离&#xff0c;对于许多应用领…

【广州华锐视点】仓储物流3D数字孪生平台打造更高效、智能的物流管理体验

在当今快速发展的物流行业中&#xff0c;传统的管理和监控方法往往难以满足复杂运营的需求。为了解决这个问题&#xff0c;广州华锐互动提供仓储物流3D数字孪生平台定制开发服务&#xff0c;打造更为高效、智能的物流管理体验。 仓储物流3D数字孪生平台是一种基于虚拟现实技术的…

DNS漫游指南:从网址到IP的奇妙之旅

当用户在浏览器中输入特定网站时发生的整个端到端过程可以参考下图 1*4vb-NMUuYTzYBYUFSuSKLw.png 问题&#xff1a; 什么是 DNS&#xff1f; 答案 → DNS 指的是域名系统&#xff08;Domain Name System&#xff09;。DNS 是互联网的目录&#xff0c;将人类可读的域名&#…