博客
关于我
python_day10 协程 GEVENT
阅读量:796 次
发布时间:2023-03-09

本文共 2694 字,大约阅读时间需要 8 分钟。

Gevent 是一个第三方库,能够轻松实现并发同步或异步编程,主要通过 Greenlet 模式以 C 扩展模块形式接入 Python。Greenlet 协程完全运行在主程序操作系统进程的内部,但通过协作式调度实现并发执行。

要使用 Gevent,首先需要执行以下操作:

import geventfrom gevent import monkey; monkey.patch_all()

这样可以确保 Gevent 能够识别并处理 I/O 阻塞。接下来,可以通过 gevent.spawn() 创建协程对象。例如:

g1 = gevent.spawn(eat, 1, 2, 3, x=4, y=5)

每个协程的执行流程如下:

def eat():    print('eat food 1')    gevent.sleep(2)  # 模拟 I/O 阻塞    print('eat food 2')

为了等待多个协程同时完成,可以使用 gevent.joinall() 方法:

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

需要注意的是,gevent.sleep() 能够识别 I/O 阻塞操作,而 time.sleep() 等则需要通过 Gevent 的补丁机制才能识别。因此,在使用 Gevent 时,应确保在模块级别执行以下代码:

from gevent import monkey; monkey.patch_all()

这样可以让 Gevent 能够正确识别并处理所有需要的阻塞操作。

协程应用示例

假设有一个简单的任务函数:

def task(pid):    gevent.sleep(0.5)    print('Task %s done' % pid)

可以通过以下方式同时执行多个任务:

import geventdef synchronous():    for i in range(1, 10):        gevent.spawn(task, i)def asynchronous():    threads = [gevent.spawn(task, i) for i in range(10)]    gevent.joinall(threads)print('Synchronous:')synchronous()print('Asynchronous:')asynchronous()

通过 gevent.joinall(),主程序会等待所有协程完成后才继续执行。

蜘蛛应用示例

以下是一个基于 Gevent 的蜘蛛应用示例:

from gevent import monkey; monkey.patch_all()import geventimport requestsimport timedef 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 服务器应用

以下是一个基于 Gevent 的 socket 服务器应用示例:

from gevent import monkey; monkey.patch_all()from socket import *import geventdef 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)

客户端可以通过以下代码连接到服务器:

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'))

通过 Gevent,可以轻松实现多协程的 socket 服务器应用。

转载地址:http://qclfk.baihongyu.com/

你可能感兴趣的文章