协程

进程:
数据隔离
数据不安全
操作系统级别
开销大
能利用多核

线程:
数据共享
数据不安全
操作系统级别
开销小
不能利用多核
对io操作的感知比较敏感(一些和文件操作相关的io只有操作系统能感知到)

协程:
数据共享
数据安全
操作系统不可见的
用户级别的
协程所有的切换都是基于用户的,只能根据用户级别能感知到的io操作
做切换来规避(socket, 请求网页...)
开销更小
不能利用多核
本质就是一条线程 多个任务在一条线程上来回切换,
利用协程这个概念实现的内容:来规避io操作即尽可能将io操作降低到最低

切换 并 规避io 的两个模块:
gevent 利用了 greenlet 底层模块完成的切换 + 自动规避io的功能

asyncio 利用了 yield 底层语法完成的切换 + 自动规避io的功能
tornado 异步的web框架
yield from - 其实是为了更好的实现协程
send

asyncio模块 基于python原生的协程的概念正式成立
特殊的在python中提供协程功能的关键字:async await

用户级别的协程有什么好处:
减轻了操作系统的负担
一条线程如果开了多条协程,那么给操作系统造成线程很忙的假象,这样能多争取一些时间片的时间
来被cpu执行,这样提高了程序的效率

2.gevent模块实现协程

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


def func():  # 带有io操作的内容写在函数里,然后将函数交给gevent
    print('start func')
    time.sleep(1)
    print('end func')


g1 = gevent.spawn(func)
g2 = gevent.spawn(func)
g3 = gevent.spawn(func)

# g1.join()  # 阻塞,直到协程g1任务执行结束
# g2.join()
# g3.join()
gevent.joinall([g1, g2, g3])

3.gevent实现socket并发的例子

server端

import socket
print(socket.socket)   # path_all()前打印一次
from gevent import monkey  # gevent如何检测是否能规避某个模块的io操作
monkey.patch_all()
import socket
print(socket.socket)   # path_all()之后打印一次,不一样则有效
import gevent


def func(conn):
    while True:
        msg = conn.recv(1024).decode('utf-8')
        MSG = msg.upper()

        conn.send(MSG.encode('utf-8'))


sk = socket.socket()
sk.bind(('ip', port))
sk.listen()

while True:
    conn, _ = sk.accept()

    gevent.spawn(func, conn)

client端

import socket
import time
from threading import Thread


def func(sk):

    while True:
        sk.send(b'hello')

        msg = sk.recv(1024)
        print(msg)
        time.sleep(0.5)


sk = socket.socket()
sk.connect(('10.19.50.157', 9001))

for i in range(500):
    Thread(target=func, args=(sk, )).start()

4.asyncio模块实现协程

import asyncio


async def func(name):
    print('start', name)
    # await + 可能会发生阻塞的方法
    # await 必须写在一个async函数里
    await asyncio.sleep(1)
    print('end')


loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait([func('alex'), func('lgq')]))
原文地址:https://www.cnblogs.com/GOD-L/p/13781807.html