zoukankan      html  css  js  c++  java
  • 【2020Python修炼记】python并发编程(七)协程

     

    一、什么是协程

    引例:

    import time
    
    # 串行执行计算密集型的任务   1.2372429370880127
    def func1():
        for i in range(10000000):
            i + 1
    
    def func2():
        for i in range(10000000):
            i + 1
    
    start_time = time.time()
    func1()
    func2()
    print(time.time() - start_time)
    
    切换 + yield  2.1247239112854004
    import time
    
    
    def func1():
        while True:
            10000000 + 1
            yield
    
    
    def func2():
        g = func1()  # 先初始化出生成器
        for i in range(10000000):
            i + 1
            next(g)
    
    start_time = time.time()
    func2()
    print(time.time() - start_time)
    串行执行

    1、协程:

    # 单线程实现并发,在应用程序里控制多个任务的切换+保存状态

    # 优点:应用程序级别速度要远远高于操作系统的切换

    # 缺点:

    多个任务一旦有一个阻塞没有切,整个线程都阻塞在原地,该线程内的其他的任务都不能执行了

    一旦引入协程,就需要检测单线程下所有的IO行为, 实现遇到IO就切换,少一个都不行,

    以为一旦一个任务阻塞了,整个线程就阻塞了, 其他的任务即便是可以计算,但是也无法运行了

     

    2、协程序的目的: 想要在单线程下实现并发 并发指的是多个任务看起来是同时运行的 并发=切换+保存状态

     

    二、gevent模块-应用举例:

    from gevent import monkey;monkey.patch_all()
    import time
    from gevent import spawn
    
    """
    gevent模块本身无法检测常见的一些io操作
    在使用的时候需要你额外的导入一句话
    from gevent import monkey
    monkey.patch_all()
    又由于上面的两句话在使用gevent模块的时候是肯定要导入的
    所以还支持简写
    from gevent import monkey;monkey.patch_all()
    """
    
    
    def heng():
        print('')
        time.sleep(2)
        print('')
    
    
    def ha():
        print('')
        time.sleep(3)
        print('')
    
    def heiheihei():
        print('heiheihei')
        time.sleep(5)
        print('heiheihei')
    
    
    start_time = time.time()
    g1 = spawn(heng)
    g2 = spawn(ha)
    g3 = spawn(heiheihei)
    g1.join()
    g2.join()  # 等待被检测的任务执行完毕 再往后继续执行
    g3.join()
    # heng()
    # ha()
    # print(time.time() - start_time)  # 5.005702018737793
    print(time.time() - start_time)  # 3.004199981689453   5.005439043045044
    gevent模块

    三、协程实现TCP服务端并发

    from gevent import monkey;monkey.patch_all()
    import socket
    from gevent import spawn
    
    
    def communication(conn):
        while True:
            try:
                data = conn.recv(1024)
                if len(data) == 0: break
                conn.send(data.upper())
            except ConnectionResetError as e:
                print(e)
                break
        conn.close()
    
    
    def server(ip, port):
        server = socket.socket()
        server.bind((ip, port))
        server.listen(5)
        while True:
            conn, addr = server.accept()
            spawn(communication, conn)
    
    
    if __name__ == '__main__':
        g1 = spawn(server, '127.0.0.1', 8080)
        g1.join()
    View Code

    参考阅读:

    https://www.cnblogs.com/linhaifeng/articles/7429894.html

  • 相关阅读:
    【原】基础篇:第一篇,本节主要向大家介绍Ext的最基础的话题
    【原】基础篇:第七篇,Ext组件系列之label组件的基本用法
    【原】基础篇:第三篇,常用的一些Ext方法
    框架
    【原】基础篇:第六篇,Ext组件系列之button组件的基本用法
    序列化
    【原】基础篇:第四篇,Ext中有两个很重要的方法,一个是decode;一个是encode.
    Arrays.asList详解
    JSP页面导出CSV查询结果
    Log的重要性
  • 原文地址:https://www.cnblogs.com/bigorangecc/p/12790311.html
Copyright © 2011-2022 走看看