• doraemon的python 协程


    ### 9.8 协程
    
    进程、线程、协程三者的区别:
    
    - 进程:是资源分配最小的单位
    - 线程:是CPU执行的最小单位
    - 协程:用户级别的,由我们自己写的python代码来控制切换的,操作系统不可见
    
    协程的意义:
    
    ```python
    #在Cpython解释器下 - 协程和线程都不能利用多核,都是在一个CPU上轮流执行
        # 由于多线程本身就不能利用多核
        # 所以即便是开启了多个线程也只能轮流在一个CPU上执行
        # 协程如果把所有任务的IO操作都规避掉,只剩下需要使用CPU的操作
        # 就意味着协程就可以做到题高CPU利用率的效果
    ```
    
    多线程和协程:
    
    ```python
    # 线程 切换需要操作系统,开销大,操作系统不可控,给操作系统的压力大
        # 操作系统对IO操作的感知更加灵敏
    # 协程 切换需要python代码,开销小,用户操作可控,完全不会增加操作系统的压力
        # 用户级别能够对IO操作的感知比较低
        
    注意:我们写的协程只能切换我们能够感知到的IO操作,但是对于无法感知的IO操作依然需要依赖线程
    ```
    
    #### 9.8.1 gevent模块
    
    ```python
    import time
    import gevent
    from gevent import monkey #本来gevent模块不认识time模块,这个帮助识别
    monkey.patch_all()
    def eat():
        print('liujia is eating')
        time.sleep(1)
        print('liujia finished eat')
        
    def sleep():
        print('liudanni is sleep')
        time.sleep(1)
        print('liudanni finised')
        
    g1 = gevent.spawn(eat)  #创造一个协程任务,遇到IO操作就自动切换
    g2 = gevent.spawn(sleep)
    g1.join()  #阻塞,直到g1任务完成为止 如果不阻塞切换了就不会切换回来了
    g2.join()
    gevent.joinall([g1,g2]) #将要阻塞的统一放进来阻塞
    print(g1.value)  #取结果
    #开启10个协程
    g_l = []
    for i inrange(10):
        g = gevent.spawn(eat)
        g_l.append(g)
    gevent.joinall(g_l)
    ```
    
    #### 9.8.2 asyncio模块
    
    ```python
    #启动一个任务
    async def demo():   #协程方法
        print('start')
        await asyncio.sleep(1) #阻塞
        print('end')
        
    loop = asyncio.get_event_loop() #创建一个时间循环
    loop.eun_until_complete(demo()) #把demo任务丢到时间循环中去执行
    ```
    
    ```python
    #地洞多个任务,并且没有返回值
    async def demo():   # 协程方法
        print('start')
        await asyncio.sleep(1)  # 阻塞
        print('end')
    
    loop = asyncio.get_event_loop()  # 创建一个事件循环
    wait_obj = asyncio.wait([demo(),demo(),demo()])
    loop.run_until_complete(wait_obj)
    ```
    
    ```python
    #启动多个任务并且有返回值
    async def demo():   # 协程方法
        print('start')
        await asyncio.sleep(1)  # 阻塞
        print('end')
        return 123
    
    loop = asyncio.get_event_loop()
    t1 = loop.create_task(demo())
    t2 = loop.create_task(demo())
    tasks = [t1,t2]
    wait_obj = asyncio.wait([t1,t2])
    loop.run_until_complete(wait_obj)
    for t in tasks:
        print(t.result())
    
    ```
    
    ```python
    #谁先回来先取谁的结果
    import asyncio
    async def demo(i):   # 协程方法
        print('start')
        await asyncio.sleep(10-i)  # 阻塞
        print('end')
        return i,123
    
    async def main():
        task_l = []
        for i in range(10):
            task = asyncio.ensure_future(demo(i))
            task_l.append(task)
        for ret in asyncio.as_completed(task_l):
            res = await ret
            print(res)
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    
    ```
  • 相关阅读:
    【Oracle 故障处理一则】 ORA-600
    【转载】关于物化视图
    【转载】OTLP和OLAP的区别
    【转载】Linux追加虚拟内存Swap
    【转载】Keepalived 的使用
    【识记】修复oracle的坏块
    K-means算法[聚类算法]
    决策树ID3算法[分类算法]
    6)图[1]之邻接矩阵存储[深度遍历和广度遍历]
    2)杨辉三角[2]递归实现
  • 原文地址:https://www.cnblogs.com/doraemon548542/p/11442743.html
Copyright © 2020-2023  润新知