首页 > 系统相关 >Python学习多线程、多进程、多协程记录

Python学习多线程、多进程、多协程记录

时间:2023-12-13 09:57:41浏览次数:40  
标签:__ Python 多协程 read 线程 result time import 多线程

一、多线程

应用于 请求和IO

#1. Python中关于使用多线程多进程的库/模块

image

#2. 选择并发编程方式 (多线程Thread、多进程Process、多协程Coroutine)

前置知识:
	一、三种有各自的应用场景
		1. 一个进程中可以启动多个线程
		2. 一个线程中可以启动多个协程

	二、各自优缺点
		1). 多线程Thread: (multiprocessing) [CPU密集型计算]
			优点:可以利用多核CPU併行运算
			缺点:占用资源最多、可启动数目比线程少

		2). 多进程Process: (threading) [IO密集型计算、同时运行的任务数目要求不多]
			优点: 相比进程、更轻量级、占用资源少
			缺点:
				相比进程:多线程只能并发执行,不能利用多CPU(GIL/全局解释器锁) 
				相比协程:启动数目有限制,占用内存资源,有线程切换开销
		
		3). 多协程Coroutine: (asyncio) [IO密集型计算、需要超多任务运行、但有现成库支持的场景]
			优点:内存开销最少、启动协程数量最多
			缺点:支持的库有限制(aiohttp(支持) vs requests(不支持))、代码实现复杂
	
	三、如何选择
	![image](/i/l/?n=23&i=blog/2580807/202312/2580807-20231207234329609-935232815.png)

#3. 线程安全Lock

用法1: try-finally模式
import threading
lock = threading.Lock()  #要写在最外层


lock.acquire() #与try..finally同层
try:
   #do something
finally:
   lock.release()
用法2: with模式
import threading
lock = threading.Lock() #要写在最外层


whith lock:
   # do something

#4. 线程池ThreadPoolExecutor

原理: 
![image](/i/l/?n=23&i=blog/2580807/202312/2580807-20231208220345011-391299606.png)

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

def add(a, b):
    return a+b

a_list = [1, 3, 5, 7, 9]
b_list = [2, 4, 6, 8, 10]

用法一: 运用map函数
#map()实现方法
with ThreadPoolExecutor(max_workers=5) as pool:
    results = pool.map(add, a_list, b_list)
    print(list(results))


用法二: future模式, 更强大
#futures实现方法
with ThreadPoolExecutor(max_workers=5) as pool:
    futures = [pool.submit(add, a_list[i], b_list[i]) for i in range(5)]
    for future in futures:
        print(future.result())

    for future in as_completed(futures):
        print(future.result()) #乱序输出

#5. Python使用线程池在Web服务中实现加速

优化之前:
import flask
import json
import time

app = flask.Flask(__name__)


def read_file():
    time.sleep(0.1)
    return 'file result'


def read_db():
    time.sleep(0.2)
    return 'db result'


def read_api():
    time.sleep(0.3)
    return 'api result'


@app.route("/")
def index():
    result_file = read_file()
    result_db = read_db()
    result_api = read_api()
    return json.dumps({
        "result_file": result_file,
        "result_db": result_db,
        "result_api": result_api,
    })

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

优化之后:
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 'db result'


def read_api():
    time.sleep(0.3)
    return 'api result'


@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()

二、多进程

#6. 多进程multiprocessing

image


三、多协程(单线程)

image
IO部分默认后台执行: 用await关键字
CPU部分优先执行: 用async定义

#7. Python异步lO实现并发爬虫 asyncio

requests不支持asyncio, 需要用aiohttp、httpx

import asyncio
#获取事件循环
loop asyncio.get_event_loop()
#定义协程
async def myfunc(url):
	await get_url(url) #对应IO
#创建task列表
tasks = [loop.create_task(myfunc(url)) for url in urls]
#执行爬虫事件列表
loop.run_until_complete(asyncio.wait(tasks))
import asyncio
import aiohttp
import  spider_common as sc
import time

async def async_craw(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            result = await resp.text()
            print(f"craw url: {url}, {len(result)}")


loop = asyncio.get_event_loop()

tasks = [
    loop.create_task(async_craw(url))
    for url in sc.urls
]

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

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

image

标签:__,Python,多协程,read,线程,result,time,import,多线程
From: https://www.cnblogs.com/cococici/p/17880610.html

相关文章

  • Python各种奇奇怪怪的写法以及常用案例
    工具类common#####工具类commonimportrequestsimporttimeimportjsonimportrandomimportosfromlxmlimportetreeimportconcurrent.futuresfromurllib.parseimportunquote,quotefromPILimportImagedefstrClear_v1(str):try:returnst......
  • 用python实现电子公文传输系统中遇到的数据库连接问题
    在实现电子公文传输系统时,数据库连接是一个重要的问题。Python中有多种库可以用于数据库连接,比如SQLite、MySQL、PostgreSQL等。下面是一个简单的示例,演示如何使用Python连接MySQL数据库:importmysql.connector#连接数据库conn=mysql.connector.connect(host="localhos......
  • python 报错应对列表
    =========================RESTART:D:/Python37/ziti1.py========================Traceback(mostrecentcalllast):File"D:/Python37/ziti1.py",line1,in<module>importdocxModuleNotFoundError:Nomodulenamed'docx'>>......
  • python123——西游记相关的分词,出现次数最高的20个
       #统计西游记人物出场次数,(去除冠词,代词等干扰)并降序排列p173importjiebaexcludes={"一个","那里","怎么","我们","不知","两个","甚么","不是","只见","原来","如何","这个","不曾&q......
  • python hash
    python中的hash我的博客程序源码原书:《Python全栈安全》这里使用python3.8,使用哈希函数计算消息的摘要信息,得到其哈希值(散列值)。在python下可以使用如下语句得到消息的哈希值:message='message'hash(message)哈希具有如下特性:确定性,相同的消息使用同一个哈希函数......
  • 深入解析Python网络编程与Web开发:urllib、requests和http模块的功能、用法及在构建现
     网络和Web开发是Python中不可或缺的重要领域,而其核心模块如urllib、requests和http在处理网络请求、HTTP请求和响应以及Web开发中扮演着关键的角色。这些模块为开发者提供了丰富的工具,使其能够灵活处理网络通信、构建Web应用和与远程服务器进行交互。深入了解这些模块的用法和作......
  • Python高级之闭包函数
    闭包函数【一】闭包函数的定义闭包(Closure)是指在函数内部定义的函数,并且这个内部函数可以访问外部函数的变量。这种机制允许函数保留对它创建时可见的变量的访问权,即使在其生命周期结束后也可以使用。闭包的主要特点是:内部函数定义在外部函数内部。内部函数可以引用外部函数......
  • Python项目之员工管理系统-函数版
    员工管理系统#完成以下功能'''---------------员工系统---------------1:注册2:登陆3:添加员工信息4:查看指定员工信息5:查看所有员工信息6:删除指定员工信息......
  • c++ 多线程
    https://blog.csdn.net/sjc_0910/article/details/118861539unique_lock和lock_guard多线程是一种实现并发处理的有效方式,C++11开始引入了<thread>库,使得多线程编程更加容易和高效。以下是C++中多线程编程的一些主要内容:线程的创建:在C++中,可以使用std::thread类来创建一......
  • 侯哥的Python分享--系列教程
    合集-mysql(26) 1.侯哥的Python分享2019-04-162.MySQL基础1-关系型数据库与非关系型数据库2022-03-173.MySQL基础2-数据库及表的操作2022-03-174.MySQL基础3-数据库增删改操作2022-03-175.MySQL基础4-数据查询07-176.MySQL基础5-用户及权限管理07-187.MySQL基础6-常用数......