美文网首页
《Python 核心技术与实战》 学习笔记 Day21 并发编程

《Python 核心技术与实战》 学习笔记 Day21 并发编程

作者: _相信自己_ | 来源:发表于2023-02-04 16:34 被阅读0次

什么是 Asyncio

首先来区分一下 Sync(同步)和 Async(异步)的概念。

  • 所谓 Sync,是指操作一个接一个地执行,下一个操作必须等上一个操作完成后才能执行。而 - Async 是指不同操作间可以相互交替执行,如果其中的某个操作被 block 了,程序并不会等待,而是会找出可执行的操作继续执行。
    举个简单的例子,你的老板让你做一份这个季度的报表,并且邮件发给他。
  • 如果按照 Sync 的方式,你会先向软件输入这个季度的各项数据,接下来等待 5min,等报表明细生成后,再写邮件发给他。
  • 但如果按照 Async 的方式,再你输完这个季度的各项数据后,便会开始写邮件。等报表明细生成后,你会暂停邮件,先去查看报表,确认后继续写邮件直到发送完毕。

Asyncio 工作原理

事实上,Asyncio 和其他 Python 程序一样,是单线程的,它只有一个主线程,但是可以进行多个不同的任务(task),这里的任务,就是特殊的 future 对象。这些不同的任务,被一个叫做 event loop 的对象所控制。你可以把这里的任务,类比成多线程版本里的多个线程。

Asyncio 用法


import asyncio
import aiohttp
import time

async def download_one(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            print('Read {} from {}'.format(resp.content_length, url))

async def download_all(sites):
    tasks = [asyncio.create_task(download_one(site)) for site in sites]
    await asyncio.gather(*tasks)

def main():
    sites = [
        'https://en.wikipedia.org/wiki/Portal:Arts',
        'https://en.wikipedia.org/wiki/Portal:History',
        'https://en.wikipedia.org/wiki/Portal:Society',
        'https://en.wikipedia.org/wiki/Portal:Biography',
        'https://en.wikipedia.org/wiki/Portal:Mathematics',
        'https://en.wikipedia.org/wiki/Portal:Technology',
        'https://en.wikipedia.org/wiki/Portal:Geography',
        'https://en.wikipedia.org/wiki/Portal:Science',
        'https://en.wikipedia.org/wiki/Computer_science',
        'https://en.wikipedia.org/wiki/Python_(programming_language)',
        'https://en.wikipedia.org/wiki/Java_(programming_language)',
        'https://en.wikipedia.org/wiki/PHP',
        'https://en.wikipedia.org/wiki/Node.js',
        'https://en.wikipedia.org/wiki/The_C_Programming_Language',
        'https://en.wikipedia.org/wiki/Go_(programming_language)'
    ]
    start_time = time.perf_counter()
    asyncio.run(download_all(sites))
    end_time = time.perf_counter()
    print('Download {} sites in {} seconds'.format(len(sites), end_time - start_time))
    
if __name__ == '__main__':
    main()

## 输出
Read 63153 from https://en.wikipedia.org/wiki/Java_(programming_language)
Read 31461 from https://en.wikipedia.org/wiki/Portal:Society
Read 23965 from https://en.wikipedia.org/wiki/Portal:Biography
Read 36312 from https://en.wikipedia.org/wiki/Portal:History
Read 25203 from https://en.wikipedia.org/wiki/Portal:Arts
Read 15160 from https://en.wikipedia.org/wiki/The_C_Programming_Language
Read 28749 from https://en.wikipedia.org/wiki/Portal:Mathematics
Read 29587 from https://en.wikipedia.org/wiki/Portal:Technology
Read 79318 from https://en.wikipedia.org/wiki/PHP
Read 30298 from https://en.wikipedia.org/wiki/Portal:Geography
Read 73914 from https://en.wikipedia.org/wiki/Python_(programming_language)
Read 62218 from https://en.wikipedia.org/wiki/Go_(programming_language)
Read 22318 from https://en.wikipedia.org/wiki/Portal:Science
Read 36800 from https://en.wikipedia.org/wiki/Node.js
Read 67028 from https://en.wikipedia.org/wiki/Computer_science
Download 15 sites in 0.062144195078872144 seconds

这里的 Async 和 await 关键字是 Asyncio 的最新写法,表示这个语句 / 函数是 non-block 的,正好对应前面所讲的 event loop 的概念。如果任务执行的过程需要等待,则将其放入等待状态的列表中,然后继续执行预备状态列表里的任务。

多线程还是 Asyncio

总的来说,你可以遵循以下伪代码的规范:


if io_bound:
    if io_slow:
        print('Use Asyncio')
    else:
        print('Use multi-threading')
else if cpu_bound:
    print('Use multi-processing')
  • 如果是 I/O bound,并且 I/O 操作很慢,需要很多任务 / 线程协同实现,那么使用 Asyncio 更合适。
  • 如果是 I/O bound,但是 I/O 操作很快,只需要有限数量的任务 / 线程,那么使用多线程就可以了。
  • 如果是 CPU bound,则需要使用多进程来提高程序运行效率。

相关文章

  • 双11Java程序员书单推荐

    Java 《Java核心技术卷I》 《Java核心技术卷II》 《Java编程思想》 《Java并发编程实战》 《...

  • Python核心技术与实战笔记目录

    参考资料: 极客时间 Python核心技术与实战学习 Python核心技术与实战(极客时间)链接:http://g...

  • Java高并发 -- 并发扩展

    Java高并发 -- 并发扩展 主要是学习慕课网实战视频《Java并发编程入门与高并发面试》的笔记 死锁 死锁是指...

  • Java高并发--AQS

    Java高并发--AQS 主要是学习慕课网实战视频《Java并发编程入门与高并发面试》的笔记 AQS是Abstra...

  • 有追求的程序员书单

    Java经典进阶书籍 Effective Java Java编程思想 Java并发编程实战 Java核心技术卷一 ...

  • Java高并发 -- 线程池

    Java高并发 -- 线程池 主要是学习慕课网实战视频《Java并发编程入门与高并发面试》的笔记 在使用线程池后,...

  • Java高并发--安全发布对象

    Java高并发--安全发布对象 主要是学习慕课网实战视频《Java并发编程入门与高并发面试》的笔记 发布对像:使一...

  • Python02 数据结构:字典和集合

    以下主要是听极客时间:Python核心技术与实战时做的笔记 对于每一门编程语言,数据结构都是重中之重。对于Pyth...

  • Python01 数据结构:列表和元组

    以下主要是听极客时间:Python核心技术与实战时做的笔记 对于每一门编程语言,数据结构都是重中之重。对于Pyth...

  • Java高并发--消息队列

    Java高并发--消息队列 主要是学习慕课网实战视频《Java并发编程入门与高并发面试》的笔记 举个例子:在购物商...

网友评论

      本文标题:《Python 核心技术与实战》 学习笔记 Day21 并发编程

      本文链接:https://www.haomeiwen.com/subject/vgvohdtx.html