zoukankan      html  css  js  c++  java
  • Python-Basis-20th

    周四,晴,记录生活分享点滴

    参考博客:https://www.cnblogs.com/alex3714/articles/5248247.html

    Python版本:3.5

    协程介绍

    协程是一种用户态的轻量级线程。(协程是一个单线程,效率高)

    好处:

    • 无需线程上下文切换的开销
    • 无需原子操作锁定及同步的开销
    • "原子操作(atomic operation)是不需要synchronized",所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序是不可以被打乱,或者切割掉只执行部分。视作整体是原子性的核心。
    • 方便切换控制流,简化编程模型
    • 高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理。

    缺点:

    • 无法利用多核资源:协程的本质是个单线程,它不能同时将 单个CPU 的多个核用上,协程需要和进程配合才能运行在多CPU上.当然我们日常所编写的绝大部分应用都没有这个必要,除非是cpu密集型应用。
    • 进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序

    yield实现协程操作(最底层)

    import time
    import queue
    def consumer(name):  # def中有yield表示consumer是生成器
        print("--->starting...")
        while True:
            new_baozi = yield  # next(con)结束
            print("[%s] is eating baozi %s" % (name,new_baozi))
            #time.sleep(1)
     
    def producer():
     
        next(con)  # 接收yield返回值
        next(con2)
        n = 0
        while n < 5:  # 当n=5时producer执行结束
            n += 1
            con.send(n)  # 从new_baozi开始,再次到yield结束
            con2.send(n)
            print("33[32;1m[producer]33[0m is making baozi %s" %n )
     
     
    if __name__ == '__main__':
        con = consumer("c1")  # 创建一个生成器对象con
        con2 = consumer("c2")  # 创建一个生成器对象con2
        p = producer()  # 执行producer函数,p是函数的返回值

    greenlet (gevent下的模块)

    from greenlet import greenlet
     
     
    def test1():
        print(12)
        gr2.switch()
        print(34)
        gr2.switch()
     
     
    def test2():
        print(56)
        gr1.switch()
        print(78)
     
     
    gr1 = greenlet(test1)
    gr2 = greenlet(test2)
    gr1.switch()
    
    """
    12
    56
    34
    78
    """

    gevent

    Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet

    import gevent
     
    def foo():
        print('Running in foo')
        gevent.sleep(1)  # 模拟IO阻塞情况
        print('Explicit context switch to foo again')
     
    def bar():
        print('Explicit context to bar')
        gevent.sleep(2)
        print('Implicit context switch back to bar')
     
    # 协程下2秒钟可以打印结果,相对于串行节省1秒 
    gevent.joinall([
        gevent.spawn(foo),
        gevent.spawn(bar),
    ])

    示例

    from gevent import monkey; monkey.patch_all()  # 补丁:最大程度监听IO阻塞
    import gevent
    from  urllib.request import urlopen
     
    def f(url):
        print('GET: %s' % url)
        resp = urlopen(url)
        data = resp.read()
        print('%d bytes received from %s.' % (len(data), url))
     
    gevent.joinall([
            gevent.spawn(f, 'https://www.python.org/'),
            gevent.spawn(f, 'https://www.yahoo.com/'),
            gevent.spawn(f, 'https://github.com/'),
    ])
  • 相关阅读:
    CCS中cmd文件的编写
    makefile与动态链接库案例分析——动态库链接动态库
    LD的-rpath,-rpath-link
    动态库的链接和链接选项-L,-rpath-link,-rpath
    JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解
    使用插件扩展Docker
    Docker 的插件式设计
    关于Docker目录挂载的总结(转)
    服务器TIME_WAIT和CLOSE_WAIT详解和解决办法
    转:基于Jmeter的MQTT测试插件
  • 原文地址:https://www.cnblogs.com/chungzhao/p/13092212.html
Copyright © 2011-2022 走看看