当前位置:   article > 正文

python线程池 异步_python异步(线程池,协程)概述

线程池和异步协程

多线程和多进程:

优点:可以为阻塞操作提供异步执行

缺点:无法无限制的创建线程

进程池和线程池

好处:可以系统对进程和线程的创建和销毁的频率,从而降低系统的开销

缺点:线程池和进程池是固定的。有上限。

线程池的基本使用

#导入进程池的pool

from multiprocessing.dummy importPool#实例化线程对象

pool = Pool(4)#map func iterator chunksize

pool.map(get_page,name_list)

协程:

单线程+异步协程(推介)

evelent_loop: 事件循环,相当于一个无限循环,可以把一些函数注册到这个循环中

coroutine:协程对象,我们可以把协程对象注册到事件循环中

task:任务,他是对协程对象的进一步封装,包含了任务的每个状态

future;代表将来执行或还没有执行的任务,task和future没有本质区别

async: 定义一个协程

await:永安里挂起阻塞方法的执行

importasyncio#提供了async await 两个关键字

asyncdefrequests1(url):print('正在请求的url',url)print('请求成功',url)#async 修饰的函数,调用之后返回的是一个协程对象

c = requests1('http://www.baidu.com')print(c)#创建一个事件循环对象

loop =asyncio.get_event_loop()#将协程对象注册到loop中,然后启动loop c 是协程对象

loop.run_until_complete(c)#task 的使用

loop=asyncio.get_event_loop()

task= loop.create_task(c) #将协程对象 传入loop ,loop创建一个task对象

print(task) #打印任务对象,正在执行,协程状态

#将任务对象注册到loop

loop.run_until_complete(task)print(task) #打印任务对象,表示任务已经完成

#future

loop=asyncio.get_event_loop()#创建future对象

task= asyncio.ensure_future(c) #任务对象

print(task)

loop.run_until_complete(task)#注册

print(task)

绑定回调函数

1 importasyncio2 #提供了async await 两个关键字

3

4 async defrequests1(url):5 print('正在请求的url',url)6

7 print('请求成功',url)8 returnurl9 #async 修饰的函数,调用之后返回的是一个协程对象

10 c = requests1('http://www.baidu.com')11

12 print(c)13

14

15

16 #绑定回调

17

18 defcallback_func(task):19 print(task.result()) #task.result() 返回任务对象的返回值

20

21 loop =asyncio.get_event_loop()22 task =asyncio.ensure_future(c)23 #当任务对象执行成功之后,执行回调函数 , 将回调函数绑定到任务对象

24 task.add_done_callback(callback_func) #默认将任务对象作为参数传递给回调函数

25 loop.run_until_complete(task)

多任务异步协程实现

importasyncioimporttime

asyncdefrequest(url):print('正在下载:',url)

time.sleep(3)print("下载完成",url)

urls=['https://www.baidu.com','https://www.sougou.com','https://www.xinlang.com',

]

start=time.time()#任务列表,需要粗放多个任务对象

tasks =[]for url inurls:

c= request(url) #协程对象

task = asyncio.ensure_future(c) #任务对象

tasks.append(task)

loop= asyncio.get_event_loop() #事件循环

loop.run_until_complete(asyncio.wait(tasks)) #注册

print(time.time()-start) #9秒, 没有节省时间

原因出在哪里?

time.sleep(3)

在异步协程中,如果出现同步模块相关的代码,那么就无法实现异步。

解决

asyncio.sleep(3)

当在asyncio中遇到阻塞操作必须进行手动挂起

awaitimportasyncioimporttime

asyncdefrequest(url):print('正在下载:',url)#time.sleep(3)

await asyncio.sleep(3)print("下载完成",url)

urls=['https://www.baidu.com','https://www.sougou.com','https://www.xinlang.com',

]

start=time.time()#任务列表,需要粗放多个任务对象

tasks =[]for url inurls:

c= request(url) #协程对象

task = asyncio.ensure_future(c) #任务对象

tasks.append(task)

loop= asyncio.get_event_loop() #事件循环

loop.run_until_complete(asyncio.wait(tasks)) #注册

print(time.time()-start) #3.003420114517212秒,

aiohttp+多任务异步协程

importasyncioimportaiohttpimportrequestsimporttime

urls=['https://www.baidu.com','https://www.sougou.com','https://www.bilibili.com/','https://www.bilibili.com/','https://www.bilibili.com/','https://www.bilibili.com/','https://www.bilibili.com/','https://www.bilibili.com/','https://www.bilibili.com/',

]

asyncdefget_page(url):print("正在下载", url)

res= requests.get(url) #基于同步代码 , 必须使用基于异步的网络请求模块

print(res.status_code)print("下载外币",url)

start=time.time()

tasks=[]for url inurls:

c=get_page(url)

task=asyncio.ensure_future(c)

tasks.append(task)

loop=asyncio.get_event_loop()

loop.run_until_complete(asyncio.wait(tasks))print(time.time()-start) #2.431379795074463

aiohttp:

pip install aiohttp

使用该模块的clientsesession

import asyncio

import aiohttp

import requests

import time

urls = [

'https://www.baidu.com',

'https://www.sougou.com',

'https://www.bilibili.com/',

'https://www.bilibili.com/',

'https://www.bilibili.com/',

'https://www.bilibili.com/',

'https://www.bilibili.com/',

'https://www.bilibili.com/',

'https://www.bilibili.com/',

]

async def get_page(url):

print("正在下载", url)

# res = requests.get(url) # 基于同步代码 , 必须使用基于异步的网络请求模块

# print(res.status_code)

async with aiohttp.ClientSession() as session:

async with await session.get(url) as res :

# text() 返回字符串数据

# read() 返回二进制数据

# json() 返回json对象

# 注意获取响应数据之前,一定要使用await手动挂起

page_text = await res.text(encoding='utf8')

print(page_text)

print("下载外币",url)

start = time.time()

tasks = []

for url in urls:

c = get_page(url)

task = asyncio.ensure_future(c)

tasks.append(task)

loop = asyncio.get_event_loop()

loop.run_until_complete(asyncio.wait(tasks))

print(time.time()-start) # 1.3533799648284912

# RuntimeWarning: coroutine 'ClientResponse.text' was never awaited

# self._context.run(self._callback, *self._args)

# 注意获取响应数据之前,一定要使用await手动挂起

other

aiohttp

get ,post

ua伪装

get

headers paramas

post

headers data , proxy 代理ip不是字典,而是字符串http://ip:port

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/74870
推荐阅读
相关标签
  

闽ICP备14008679号