编程语言
首页 > 编程语言> > 并发编程与异步IO-Python

并发编程与异步IO-Python

作者:互联网

并发编程与异步IO

基本概念:并发,并行,同步,异步,阻塞,非阻塞

并发:一个时间段内,有几个程序在同一个 CPU 上运行,但是任意时刻只有一个程序在 CPU 上运行。
并行:在任意时刻点上,有多个程序同时运行在**多个 CPU **上。如果 CPU 有个四颗,那么并行最多只有四个。
基于以上,我们都说高并发,不说高并行。
同步:代码调用 IO 操作时,必须等待 IO 操作完成才返回的调用方式。
异步:指代码调用 IO 操作时,不必等 IO 操作完成就返回的调用方式。
阻塞:指调用函数时,当前线程被挂起。
非阻塞:指调用函数时,当前线程不会被挂起,而是立即返回。
阻塞和非阻塞是说的函数调用的一种机制。

多线程与多进程

CPython中,多线程thread常用来处理io密集型的操作,因为GIL的原因无法利用多核优势,如果是计算密集型的操作需要多进程multiprocess,多线程的优势在与线程之间数据共享,也真是因为数据共享所以多线程会抢占共享资源这就需要这种东西,多进程不会出现这种情况因为数据不共享嘛(相当于多个python解释器在运行),但是这也有问题,多进程通信就是一个难题.

线程模块:Threading

进程模块:Multiprocessing

懒人包:Concurrent

异步框架 asyncio

异步框架的发展由来: yield-->yield from -->gevent/greenlet-->asyncio,asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。

基本概念:

asyncio协程是如何工作的

单任务携程

单任务的携程是没有什么意义的这里主要是为了了解asyncio协程整体是如何工作的

import asyncio
import time
#1创建事件循环event_loop
loop = asyncio.get_event_loop()

#2创建携程函数
async def func1():
    await asyncio.sleep(1)
    return '1finished'
async def func2():
    await asyncio.sleep(3)
    return '2finished'

#3 携程函数转成携程对象
coroutine = func1()

#4 携程对象转成task对象
task = loop.create_task(coroutine)

#5 给task添加回调函数
def _callback(task):
    print(f'回调函数获得结果:{task.result()}')
task.add_done_callback(_callback)

#6 启动事件循环
loop.run_until_complete(task)

#7获得任务结果
print(task.result())

多任务携程并发实现

1可以用另一个函数把携程函数整合起来,并发的逻辑在整合函数中实现,但是如果方法不对可能无法实现并发

import asyncio
import time
#1创建事件循环event_loop
loop = asyncio.get_event_loop()

#2创建携程函数
async def func1():
    await asyncio.sleep(1)
    return '1finished'
async def func2():
    await asyncio.sleep(3)
    return '2finished'

#不能并发的的例子
async def test_error():
    star = time.time()
    coroutine1 = func1()
    coroutine2 = func2()
    await loop.create_task(coroutine1)
    await loop.create_task(coroutine2)
    print('all done',time.time()-star)
if __name__ == '__main__':
    loop.run_until_complete(test_error())

#这样写就可以并发了
async def test1():
    star = time.time()
    coroutine1 = func1()
    coroutine2 = func2()
    task1 = loop.create_task(coroutine1)
    task2 = loop.create_task(coroutine2)
    await task1
    await task2
    print('all done',time.time()-star)

if __name__ == '__main__':
    loop.run_until_complete(test1())
    
#通常并发的用法,使用asyncio.wait或者asyncio.gather
async def test2():
    star = time.time()
    coroutine1 = func1()
    coroutine2 = func2()
    task1 = loop.create_task(coroutine1)
    task2 = loop.create_task(coroutine2)
    tasks = [task1,task2]
    result = await asyncio.gather(*tasks)
    print(task1.result())
    print('all done',time.time()-star)
if __name__ == '__main__':
    loop.run_until_complete(test2())
    
    
async def test3():
    star = time.time()
    coroutine1 = func1()
    coroutine2 = func2()
    task1 = loop.create_task(coroutine1)
    task2 = loop.create_task(coroutine2)
    tasks = [task1,task2]
    await asyncio.wait(tasks)
    print(task1.result())
    print('all done',time.time()-star)
if __name__ == '__main__':
    loop.run_until_complete(test3())
    
#多任务携程回调函数的使用,依次给task添加回调函数
def callback(task):
    print(f'回调函数触发:{task.result()}')
async def test4():
    star = time.time()
    coroutine1 = func1()
    coroutine2 = func2()
    task1 = loop.create_task(coroutine1)
    task2 = loop.create_task(coroutine2)
    tasks = [task1,task2]
    for task in tasks:
        task.add_done_callback(callback)
    await asyncio.gather(*tasks)

    print('all done',time.time()-star)
if __name__ == '__main__':
    loop.run_until_complete(test3())

创建task对象的3种方法,三种方法都可,看个人习惯

loop.create_task
asyncio.create_task
asyncio.ensure_future

标签:__,异步,task,协程,Python,IO,time,loop,asyncio
来源: https://www.cnblogs.com/Franciszw/p/16476411.html