zoukankan      html  css  js  c++  java
  • 操作系统OS,Python

    留坑

    参考:

    1. https://en.wikipedia.org/wiki/Coroutine
    2. https://zh.wikipedia.org/wiki/协程
    3. http://www.cnblogs.com/xybaby/p/6323358.html

    值得注意的点:

    1. Python对协程的支持是通过generator实现的。
    2. Python中,generator的send和throw方法使得generator很像一个协程(coroutine), 但是generator只是一个半协程(semicoroutines),python doc是这样描述的:“All of this makes generator functions quite similar to coroutines; they yield multiple times, they have more than one entry point and their execution can be suspended. The only difference is that a generator function cannot control where should the execution continue after it yields; the control is always transferred to the generator’s caller.
    3. 一个线程可以多个协程,一个进程也可以单独拥有多个协程,这样python中则能使用多核CPU。(多进程+协程)
    4. greenlet是真正的协程
    5. Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。

    例子1. 用协程实现生产者,消费者模型

    1. 参考:https://blog.csdn.net/pfm685757/article/details/49924099
    2. 参考:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432090171191d05dae6e129940518d1d6cf6eeaaa969000
    """
        1. 用协程实现消费者生产者模型
        2. Python对协程的支持是通过generator实现的
        3. 有yield的话,就是generator
        4. 整个流程无锁,由一个线程执行,produce和consumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务。
    """
    
    def consumer():
        r = ''
        while True:
            # n为send过来的值
            # yield类似于断点,有两个作用。
            # 1. 生成值
            # 2. 在这里断点,交出控制权。切换到另外一个协程
            n = yield r
            if not n:
                return
            print('[CONSUMER] Consuming %s...' % n)
            r = '200 OK'
    
    def produce(c): 
        #start generator with None
        c.send(None)
        n = 0
        while n < 5:
            n = n + 1
            print('[PRODUCER] Producing %s...' % n)
            #启动生成器,并附带一个值,r接收yield生成的值
            r = c.send(n)
            print('[PRODUCER] Consumer return: %s' % r)
        c.close()
    
    c = consumer()
    
    produce(c)
    

    例子2. 遇到IO阻塞时自动切换任务,based on gevent,greenlet,monkey

    from gevent import monkey; monkey.patch_all()
    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://www.baidu.com/'),
    ])
    

    例子3. 单线程下实现多socket并发,based on gevent

    server.py

    import sys
    import socket
    import time
    import gevent
     
    from gevent import socket,monkey
    monkey.patch_all()
     
     
    def server(port):
        s = socket.socket()
        s.bind(('0.0.0.0', port))
        s.listen(500)
        while True:
            cli, addr = s.accept()
            gevent.spawn(handle_request, cli)
     
     
     
    def handle_request(conn):
        try:
            while True:
                data = conn.recv(1024)
                print("recv:", data)
                conn.send(data + '  [server]'.encode('utf-8'))
                if not data:
                    conn.shutdown(socket.SHUT_WR)
     
        except Exception as ex:
            print(ex)
        finally:
            conn.close()
    if __name__ == '__main__':
        server(8006)
    

    client.py

    import socket
    import threading
    
    def sock_conn():
    
        client = socket.socket()
    
        client.connect(("localhost",8006))
        count = 0
        while True:
            #msg = input(">>:").strip()
            #if len(msg) == 0:continue
            #从客户端收到的数据
            client.send( ("hello %s" %count).encode("utf-8"))
    
            #从服务器端收到的数据
            data = client.recv(1024)
    
            print("[%s]recv from server:" % threading.get_ident(),data.decode()) #结果
            count +=1
        client.close()
    
    
    for i in range(100):
        t = threading.Thread(target=sock_conn)
        t.start()
    
  • 相关阅读:
    第一阶段-坑爹猴
    终于做出来了
    一天就制作成了这些
    累成狗做出来的
    一周的学习,组合起来的成就
    刚刚出炉的搜狗浏览器最新版本
    自己动手设计了一下下百度首页
    数论:卢卡斯定理(求组合数)
    数据结构:ST表模板(可维护区间RMQ)
    快读和快写(可以使用__int128)
  • 原文地址:https://www.cnblogs.com/allen2333/p/8940060.html
Copyright © 2011-2022 走看看