asyncio 协程介绍:
- 动态添加任务:
- 方案是创建一个线程,使事件循环在线程内永久运行
- 设置守护进程,随着主进程一起关闭
- 自动停止协程以及线程
- 可进行任务阻塞至完成
- 协程池
- asyncio.Semaphore() 进行控制
- maxsize 设置最大并发数
demo
"""
asyncio 协程介绍:
- 动态添加任务:
- 方案是创建一个线程,使事件循环在线程内永久运行
- 设置守护进程,随着主进程一起关闭
- 自动停止任务
- 阻塞任务完成
- 协程池
- asyncio.Semaphore() 进行控制
"""
import asyncio
import aiohttp
import time
import queue
from threading import Thread
class AsyncPool(object):
"""
1. 支持动态添加任务
2. 支持自动停止事件循环
3. 支持最大协程数
"""
def __init__(self, maxsize=1, loop=None):
"""
初始化
:param loop:
:param maxsize: 默认为1
"""
self.task = queue.Queue()
self.loop, _ = self.start_loop(loop)
self.semaphore = asyncio.Semaphore(maxsize, loop=self.loop)
def task_add(self, item=1):
"""
添加任务
:param item:
:return:
"""
self.task.put(item)
def task_done(self, fn):
"""
任务完成
回调函数
:param fn:
:return:
"""
if fn:
pass
self.task.get()
self.task.task_done()
def wait(self):
"""
等待任务执行完毕
:return:
"""
self.task.join()
@property
def running(self):
"""
获取当前线程数
:return:
"""
return self.task.qsize()
@staticmethod
def _start_thread_loop(loop):
"""
运行事件循环
:param loop: loop以参数的形式传递进来运行
:return:
"""
asyncio.set_event_loop(loop)
loop.run_forever()
async def _stop_thread_loop(self, loop_time=1):
"""
停止协程
关闭线程
:return:
"""
while True:
if self.task.empty():
self.loop.stop()
break
await asyncio.sleep(loop_time)
def start_loop(self, loop):
"""
运行事件循环
开启新线程
:param loop: 协程
:return:
"""
if not loop:
loop = asyncio.new_event_loop()
loop_thread = Thread(target=self._start_thread_loop, args=(loop,))
loop_thread.setDaemon(True)
loop_thread.start()
return loop, loop_thread
def stop_loop(self, loop_time=1):
"""
队列为空,则关闭线程
:param loop_time:
:return:
"""
asyncio.run_coroutine_threadsafe(self._stop_thread_loop(loop_time), self.loop)
def release(self, loop_time=1):
"""
释放线程
:param loop_time:
:return:
"""
self.stop_loop(loop_time)
async def async_semaphore_func(self, func):
"""
信号包装
:param func:
:return:
"""
async with self.semaphore:
return await func
def submit(self, func, callback=None):
"""
提交任务到事件循环
:param func: 异步函数对象
:param callback: 回调函数
:return:
"""
self.task_add()
future = asyncio.run_coroutine_threadsafe(self.async_semaphore_func(func), self.loop)
future.add_done_callback(callback)
future.add_done_callback(self.task_done)
async def thread_example(i):
url = "http://127.0.0.1:8080/app04/async4?num={}".format(i)
async with aiohttp.ClientSession() as session:
async with session.get(url) as res:
return await res.text()
def my_callback(future):
result = future.result()
print('返回值: ', result)
def main():
pool = AsyncPool(maxsize=100000)
for i in range(100000):
pool.submit(thread_example(i), my_callback)
print("等待子线程结束1...")
pool.release()
print("等待子线程结束2...")
pool.wait()
print("等待子线程结束3...")
if __name__ == '__main__':
start_time = time.time()
main()
end_time = time.time()
print("run time: ", end_time - start_time)