zoukankan      html  css  js  c++  java
  • 并发编程之协程

    协程介绍

    协程:是单线程下的并发,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程: 协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。

    1. python的线程属于内核级别的,即由操作系统控制调度(如单线程遇到io或执行时间过长就会被迫交出cpu执行权限,切换其他线程运行)

    2. 单线程内开启协程,一旦遇到io,就会从应用程序级别(而非操作系统)控制切换,以此来提升效率(非io操作的切换与效率无关)

    对比操作系统控制线程的切换,用户在单线程内控制协程的切换

    优点:

    1. 协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级

    2. 单线程内就可以实现并发的效果,最大限度地利用cpu

    缺点:

    1. 协程的本质是单线程下,无法利用多核,可以是一个程序开启多个进程,每个进程内开启多个线程,每个线程内开启协程

    2. 协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程

    gevent模块

    Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。

    gevent模块本身无法检测常见的一些io操作, 在使用的时候需要你额外导入一句话。即导入猴子补丁

    import time
    from gevent import spawn
    from gevent import monkey
    """
    gevent模块本身无法检测常见的一些io操作, 在使用的时候需要你额外导入一句话
    from gevent import monkey
    monkey.patch_all()
    
    """
    monkey.patch_all()
    
    
    def heng():
        print('')
        time.sleep(2)
        print('')
    
    
    def ha():
        print('')
        time.sleep(3)
        print('')
    
    
    if __name__ == '__main__':
        start_time = time.time()
        g1 = spawn(heng)
        g2 = spawn(ha)
        g1.join()
        g2.join()  # 等待被检测的任务执行完毕, 在往后继续执行
        print(time.time() - start_time)  # 3.0037176609039307

    由于上面的两句话在使用gevent模块的时候是肯定要导入的, 所以还支持简写

    from gevent import monkey; monkey.patch_all()

     

    基于协程实现TCP服务并发

    from gevent import spawn
    from gevent import monkey;
    
    monkey.patch_all()
    import socket
    
    
    def communication(conn):
        while True:
            try:
                data = conn.recv(1024)
                if len(data) == 0: break
                conn.send(data.upper())
            except Exception as e:
                print(e)
    
        conn.close()
    
    
    def server(ip, port):
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.bind((ip, port))
        server.listen()
    
        while True:
            conn, addr = server.accept()
            spawn(communication, conn)
    
    
    if __name__ == '__main__':
        g1 = spawn(server, '127.0.0.1', 8080)
        g1.join()
  • 相关阅读:
    创建Variant数组
    ASP与存储过程(Stored Procedures)
    FileSystemObject对象成员概要
    Kotlin 朱涛9 委托 代理 懒加载 Delegate
    Kotlin 朱涛 思维4 空安全思维 平台类型 非空断言
    Kotlin 朱涛7 高阶函数 函数类型 Lambda SAM
    Kotlin 朱涛16 协程 生命周期 Job 结构化并发
    Proxy 代理模式 动态代理 cglib MD
    RxJava 设计理念 观察者模式 Observable lambdas MD
    动态图片 Movie androidgifdrawable GifView
  • 原文地址:https://www.cnblogs.com/featherwit/p/13391945.html
Copyright © 2011-2022 走看看