zoukankan      html  css  js  c++  java
  • python_day10 协程 GEVENT

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

    g1=gevent.spawn()创建一个协程对象g1,

    spawn括号内第一个参数是函数名,如eat,后面可以有多个参数,可以是位置实参或关键字实参,都是传给函数eat的

    import gevent
    import time


    def eat():
    print('eat food 1')
    gevent.sleep(2) #等饭来
    print('eat food 2')

    def play_phone():
    print('play phone 1')
    gevent.sleep(1) #网卡了
    print('play phone 2')

    # gevent.spawn(eat)
    # gevent.spawn(play_phone)
    # print('主') # 直接结束


    #因而也需要join方法,进程或现场的jion方法只能join一个,而gevent的join方法可以join多个

    g1=gevent.spawn(eat)
    g2=gevent.spawn(play_phone)
    gevent.joinall([g1,g2])
    print('主')

    上例gevent.sleep(2)模拟的是gevent可以识别的io阻塞,

    而time.sleep(2)或其他的阻塞,gevent是不能直接识别的需要用下面一行代码,打补丁,就可以识别了

    from gevent import monkey;monkey.patch_all()必须放到被打补丁者的前面,如time,socket模块之前

    或者我们干脆记忆成:要用gevent,需要将from gevent import monkey;monkey.patch_all()放到文件的开头

    from gevent import monkey;monkey.patch_all()

    import gevent
    import time


    def eat():
    print('eat food 1')
    time.sleep(2)
    print('eat food 2')

    def play_phone():
    print('play phone 1')
    time.sleep(1)
    print('play phone 2')

    g1=gevent.spawn(eat)
    g2=gevent.spawn(play_phone)
    gevent.joinall([g1,g2])
    print('主')

    #########同步和异步

    import gevent

    def task(pid):
    """
    Some non-deterministic task
    """
    gevent.sleep(0.5)
    print('Task %s done' % pid)

    def synchronous():
    for i in range(1,10):
    task(i)

    def asynchronous():
    threads = [gevent.spawn(task, i) for i in range(10)]
    gevent.joinall(threads)

    print('Synchronous:')
    synchronous()

    print('Asynchronous:')
    asynchronous()

    ############

    上面程序的重要部分是将task函数封装到Greenlet内部线程的gevent.spawn。 初始化的greenlet列表存放在数组threads中,此数组被传给gevent.joinall 函数,后者阻塞当前流程,并执行所有给定的greenlet。执行流程只会在 所有greenlet执行完后才会继续向下走。

    #gevent线程的一些用法
    g1=gevent.spawn(func,1,,2,3,x=4,y=5)

    g2=gevent.spawn(func2)

    g1.join() #等待g1结束

    g2.join() #等待g2结束

    #或者上述两步合作一步:gevent.joinall([g1,g2])

    g1.value#拿到func1的返回值

    ##############

    模拟爬虫应用

    from gevent import monkey;monkey.patch_all()
    import gevent
    import requests
    import time

    def get_page(url):
    print('GET: %s' %url)
    response=requests.get(url)
    if response.status_code == 200:
    print('%d bytes received from %s' %(len(response.text),url))


    start_time=time.time()
    gevent.joinall([
    gevent.spawn(get_page,'https://www.python.org/'),
    gevent.spawn(get_page,'https://www.yahoo.com/'),
    gevent.spawn(get_page,'https://github.com/'),
    ])
    stop_time=time.time()
    print('run time is %s' %(stop_time-start_time))

    协程应用:爬虫.

     ########################################

    单线程,多协程 方式 实现socket-server端

    from gevent import monkey;monkey.patch_all()
    from socket import *
    import gevent

    #如果不想用money.patch_all()打补丁,可以用gevent自带的socket
    # from gevent import socket
    # s=socket.socket()

    def server(server_ip,port):
    s=socket(AF_INET,SOCK_STREAM)
    s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
    s.bind((server_ip,port))
    s.listen(5)
    while True:
    conn,addr=s.accept()
    gevent.spawn(talk,conn,addr)

    def talk(conn,addr):
    try:
    while True:
    res=conn.recv(1024)
    print('client %s:%s msg: %s' %(addr[0],addr[1],res))
    conn.send(res.upper())
    except Exception as e:
    print(e)
    finally:
    conn.close()

    if __name__ == '__main__':
    server('127.0.0.1',8080)

    服务端

    ###################client

    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'

    from socket import *

    client=socket(AF_INET,SOCK_STREAM)
    client.connect(('127.0.0.1',8080))


    while True:
    msg=input('>>: ').strip()
    if not msg:continue

    client.send(msg.encode('utf-8'))
    msg=client.recv(1024)
    print(msg.decode('utf-8'))

    客户端

  • 相关阅读:
    49. 字母异位词分组
    73. 矩阵置零
    Razor语法问题(foreach里面嵌套if)
    多线程问题
    Get json formatted string from web by sending HttpWebRequest and then deserialize it to get needed data
    How to execute tons of tasks parallelly with TPL method?
    How to sort the dictionary by the value field
    How to customize the console applicaton
    What is the difference for delete/truncate/drop
    How to call C/C++ sytle function from C# solution?
  • 原文地址:https://www.cnblogs.com/onda/p/7111626.html
Copyright © 2011-2022 走看看