协程(纤程):一个线程的多个部分。
比线程的单位更小。
在一个线程中可以开启很多协程。
在执行当前操作时,遇到I/O操作就会冻结当前操作,去执行其他任务,不断的检测上一个任务是否 -,如果I/O结束了就继续从冻结的地方开始
I/O操作是不占CPU的
协程的特点:
1.冻结当前程序任务的特点
2.可以规避I/O操作的时间
我们今天顺便讲了生成器,(用时间换了空间,每制造出一个资源就消费一个资源)
好的,!下面正式进入正题????
greenlet 切换(在携程这个模块中做多个协程之间的切换的)
from gevent import monkey;monkey.patch_all()
# 它会把下面导入的所有的模块中的IO操作都打成一个包,gevent就能够认识这些IO了
import time
import gevent
# 使用gevent模块来执行多个函数,表示在这些函数遇到IO操作的时候可以在同一个线程中进行切花
# 利用其他任务的IO阻塞时间来切换到其他的任务继续执行
# spawn来发布协程任务
# join负责开启并等待任务执行结束
# gevent本身不认识其他模块中的IO操作,但是如果我们在导入其他模块之前执行from gevent import monkey;monkey.patch_all()
# gevent就能够认识在这句话之后导入的模块中的所有IO操作了
from threading import currentThread
def eat():
print('eating1',currentThread())
time.sleep(1)
print('eating2')
def play():
print('playing1',currentThread())
time.sleep(1)
print('playing2')
g1 = gevent.spawn(eat)
g2 = gevent.spawn(play)
g1.join() # start 且等待g执行完毕
g2.join()
# 休息一会儿
# 协程——tcp 协议的socket并发server
# 异步和同步的测试from gevent import monkey;monkey.patch_all()import geventimport timedef task(i): time.sleep(0.5) print(i)def sync(): # 同步 for i in range(10): task(i)def async(): # 异步 #gevent.joinall([gevent.spawn(task, i) for i in range(10)]) g_lst = [] for i in range(10): g = gevent.spawn(task, i) g_lst.append(g) # for g in g_lst:g.join() gevent.joinall(g_lst)async()print('-'*20)sync()
# 爬取页面的例子from gevent import monkey;monkey.patch_all()from urllib.request import urlopenimport geventimport timedef get_page(url): res = urlopen(url) print(len(res.read()))url_lst = [ 'http://www.baidu.com', 'http://www.sogou.com', 'http://www.sohu.com', 'http://www.qq.com', 'http://www.cnblogs.com',]start = time.time()gevent.joinall([gevent.spawn(get_page,url) for url in url_lst])print(time.time() - start)start = time.time()gevent.joinall([gevent.spawn(get_page,url) for url in url_lst])print(time.time() - start)start = time.time()for url in url_lst:get_page(url)print(time.time() - start)server端
# from gevent import monkey;monkey.patch_all()# import socket# import gevent# def async_talk(conn):# try:# while True:# conn.send(b'hello')# ret = conn.recv(1024)# print(ret)# finally:# conn.close()# sk = socket.socket()# sk.bind(('127.0.0.1',9000))# sk.listen()# while True:# conn,addr = sk.accept()# gevent.spawn(async_talk,conn)# sk.close()
client端
# from gevent import monkey;monkey.patch_all()# import socket# import gevent# from threading import Thread# def socket_client():# sk = socket.socket()# sk.connect(('127.0.0.1',9000))# while True:# print(sk.recv(1024))# sk.send(b'bye')# sk.close()# # for i in range(500):# # Thread(target=socket_client).start()# gevent.joinall([gevent.spawn(socket_client) for i in range(500)])# 进程5 线程20 协程500个 —— 通用的组合 —— 50000# 进程 线程 协程# 并发编程的设计# 进程 线程 协程 都用
来源:https://www.cnblogs.com/zsdbk/p/9053946.html