协程本质上是一个线程,在一个线程上提高cpu的利用率

在cpython中很重要,因为多线程被弱化

能够在多个任务之间切换来节省IO时间

协程中任务之间的切换时间开销远远小于进程线程之间的切换

工作中一般4核进程(5)+线程(20)+协程(500)

进程和线程是操作系统调度(时间片)的,协程是greenlet调度的

协程更多用在网络操作(爬虫之类的)

 

协程模块gevent是用greenlet完成的

from greenlet import greenlet
def eat():
print('开吃...')
g2.switch()
print('吃完了')
g2.switch()

def play():
print('开玩...')
g1.switch()
print('玩完了')

g1 = greenlet(eat)
g2 = greenlet(play)
g1.switch()

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

 

协程爬虫:

from gevent import monkey;monkey.patch_all()
import gevent
from urllib.request import urlopen

def get_url(url):
res = urlopen(url)
content = res.read().decode('utf-8')
return len(content)

g1 = gevent.spawn(get_url,'http://www.baidu.com')
g2 = gevent.spawn(get_url,'http://www.taobao.com')
g3 = gevent.spawn(get_url,'http://www.sogou.com')
g4 = gevent.spawn(get_url,'http://www.hao123.com')
g5 = gevent.spawn(get_url,'http://www.cnblogs.com')
gevent.joinall([g1,g2,g3,g4,g5])
print(g1.value)
print(g2.value)
print(g3.value)
print(g4.value)
print(g5.value)

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

 

协程tcpsever:

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


def talk(conn):
conn.send(b'hello')
print(conn.recv(1024).decode('utf-8'))
conn.close()

sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()

while True:
conn,addr = sk.accept()
gevent.spawn(talk,conn)

sk.close()