zoukankan      html  css  js  c++  java
  • Python中greenlet和gevent使用示例

    greenlet示例

    greenlet微线程,允许在线程中手动切换

    示例1,线程切换

    from greenlet import greenlet
    
    def test1(x,y):
        z = gr2.switch(x+y)
        print(z)
    
    def test2(u):
        print(u)
        gr1.switch(42)
    
    gr1 = greenlet(test1)
    gr2 = greenlet(test2)
    gr1.switch("hello",'world')
    

    gr1和gr2是两个greenlet线程,使用gr1.switch(..)启动gr1,gr1执行test1,切换到gr2,gr2执行test2打印helloworld,然后切换回gr1,z获取到返回值42,并打印.
    执行顺序为:
    gr1.switch("hello",'world') -> test1('hello','world')->
    gr2.switch('helloword')->test2('helloworld')->print('helloworld')
    ->gr1.switch(42)->z=42->print(42)
    打印结果:

    helloworld
    42
    

    示例2

    from greenlet import greenlet
    
    def eat(name):
        print('%s eat 1' %name)
        g2.switch('egon')
        print('%s eat 2' %name)
        g2.switch()
    def play(name):
        print('%s play 1' %name)
        g1.switch()
        print('%s play 2' %name)
    
    g1=greenlet(eat)
    g2=greenlet(play)
    
    g1.switch('egon')#可以在第一次switch时传入参数,以后都不需要
    

    gevent

    gevent基于greenlet,遇到IO操作自动切换,IO操作比如网络请求,或使用 gevent.sleep(0)强制切换.

    示例1

    import gevent
    
    def func1():
        print("start func1")
        gevent.sleep(1)
        print("end func1")
    
    def func2():
         print("start func2")
        gevent.sleep(1)
        print("end func2")
    
    gevent.joinall(
        [
            gevent.spawn(func1),
            gevent.spawn(func2)
        ]
    )
    

    执行结果:

    start func1
    start func2
    end func1
    end func2
    ``
    
    ### 示例2: gevent使用monkey对所有系统自带的IO操作打patch
    ```python
    from gevent import monkey;monkey.patch_all()
    
    import gevent
    import time
    def eat():
        print('eat food 1')
        time.sleep(2)  # 会自动的跳转到play
        print('eat food 2')
    
    def play():
        print('play 1')
        time.sleep(1) # 会自动的跳转到eat
        print('play 2')
    
    g1=gevent.spawn(eat)
    g2=gevent.spawn(play)
    gevent.joinall([g1,g2])
    print('end')
    

    执行结果

    eat food 1
    play 1
    play 2
    eat food 2
    end
    

    示例3,发送请求

    from gevent import monkey; monkey.patch_all()
    import gevent
    import requests
    
    def f(url):
        print('GET: %s' % url)
        resp = requests.get(url)
        data = resp.text
        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/'),
            gevent.spawn(f, 'https://github.com/'),
            gevent.spawn(f, 'https://github.com/'),
            gevent.spawn(f, 'https://github.com/'),
            gevent.spawn(f, 'https://github.com/'),
    ])
    

    示例4:使用gevent的socket替代系统的socket

    import gevent
    from gevent import socket
    
    urls = ['www.baidu.com', 'www.163.com', 'www.qq.com']
    jobs = [gevent.spawn(socket.gethostbyname, url) for url in urls]
    gevent.joinall(jobs, timeout=2)
    
    print([job.value for job in jobs])
    
    
    或使用patch_socket()
    from gevent import monkey; monkey.patch_socket()
    import gevent
    
    def f(n):
        for i in range(n):
            print(gevent.getcurrent(), i)
            gevent.sleep(0)  # 不加的话不会交替执行
    g1 = gevent.spawn(f, 5)
    g2 = gevent.spawn(f, 5)
    g3 = gevent.spawn(f, 5)
    g1.join()
    g2.join()
    g3.join()
    

    示例5:队列中使用gevent.sleet(0)强制切换到其他线程

    import gevent
    from gevent.queue import Queue
    
    
    def func():
        for i in range(10):
            print("int the func")
            q.put(f"test{i}")
            gevent.sleep(0)
    
    def func2():
        for i in range(10):
            print("int the func2")
            res = q.get()
            print("--->",res)
    
    q = Queue()
    gevent.joinall(
        [
            gevent.spawn(func2),
            gevent.spawn(func),
        ]
    )
    
    
  • 相关阅读:
    设计模式之工厂模式(Factory Pattern)用C++实现
    读书笔记之Effective C++ 1.让自己习惯C++
    LeetCode之RemoveDuplicates扩展
    一致性哈希(Consistent Hashing)原理和实现(整理)
    LeetCode之Remove Duplicates from Sorted Array
    C++小结
    HTTP、HTTP1.0、HTTP1.1、HTTP2.0——笔记
    《趣谈网络协议》——问答笔记
    技术源于生活(头脑风暴)
    解决:未能加载文件或程序集“System.Web.Http, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
  • 原文地址:https://www.cnblogs.com/superhin/p/11586922.html
Copyright © 2011-2022 走看看