美文网首页
进阶学习7-并发/并行

进阶学习7-并发/并行

作者: 龙猫六六 | 来源:发表于2020-01-30 18:55 被阅读0次

    并发和并行

    并发

    • 同一时刻只允许一个操作,线程/任务之间相互切换,达到并发处理任务
    • 单线程:协程(asyncio)
    • 多线程:Futures(threading)
    • 并发通常应用与I/O操作频繁的场景

    并行

    • 同一时刻同时发送
    • 多进程
    • 并行通常应用于CPU heavy的场景

    单线程并发-协程

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

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

    协程使用步骤:

    • 使用asynic修饰函数,定义为异步函数
    • await调用异步函数,注意:同步调用,需要task来实现真正的并发
    • task创建:task任务asynic.create_task(异步函数)
    • task调度:创建调度器,统一调度任务 await asynic.gather(*task)
    • 运行协程:asynic.run(异步函数)
    • 第三方库要支持协程,如request不支持协程,改用aiohttp
    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

    • 全局解释器:Python 便引入了全局解释器锁,也就是同一时刻,只允许一个线程执行。当然,在执行 I/O 操作时,如果一个线程被 block 了,全局解释器锁便会被释放,从而让另一个线程能够继续执行
    描述 备注
    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()
    

    相关文章

      网友评论

          本文标题:进阶学习7-并发/并行

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