进阶学习7-并发/并行

2020-01-30  本文已影响0人  龙猫六六

并发和并行

并发

并行

单线程并发-协程

单个协程实现并发,建议使用I/O密集型场景
python3.7及以上

描述 备注
async 异步函数申明 将普通函数申明为异步函数
await 异步函数调用 同步调用异步函数,返回协程对象
asyncio.create_taks() 创建任务
asynic.gater(*tasks) 执行task
asynic.run 触发运行
协程实例

协程使用步骤:

import asyncio

async def crawl_page(url):
    print('crawling {}'.format(url))
    sleep_time = int(url.split('_')[-1])
    await asyncio.sleep(sleep_time)
    print('OK {}'.format(url))

async def main(urls):
    tasks = [asyncio.create_task(crawl_page(url)) for url in urls]
    await asyncio.gather(*tasks)

asyncio.run(main(['url_1', 'url_2', 'url_3', 'url_4']))

多线程并发- future

描述 备注
future future对象 将处于等待状态的操作包裹起来放到队列
ThreadPoolExcutor 创建线程池 max_workers=5
PorcessPoolExcutor 创建进程池 max_workers=5
executor.submit(func) func被包裹成future对象,返回future实例
future.as_completed(fn) future完成后,回调函数fn
future.result() future完成后,返回对应结果或异常

实例

from concurrent.futures import Future, ThreadPoolExecutor, as_completed
import requests
import time

def download_one(url):
    resp = requests.get(url)
    print('Read {} from {}'.format(len(resp.content), url))


def download_all(urls):
    with ThreadPoolExecutor(5) as excutor:
        to_do = []
        for url in urls:
            future = excutor.submit(download_one, url)
            to_do.append(future)

        for future in as_completed(to_do):
            future.result()


if __name__ == '__main__':
    sites = [
        "https://www.19lou.com",
        "https://food.19lou.com",
        "https://tour.19lou.com",
        "https://auto.19lou.com",
        "https://fashion.19lou.com",
        "https://sweet.19lou.com",
        "https://love.19lou.com",
        "https://marry.19lou.com",
        "https://money.19lou.com"
    ]

    st = time.perf_counter()
    download_all(sites)
    et = time.perf_counter()
上一篇 下一篇

猜你喜欢

热点阅读