协程
协程的作用就是在执行某个子程序(函数)时,可以指定或者随机地中断,然后去执行其他的子程序(函数),在合适的时候再返回到中断子程序停止时的状态继续执行。听起像生成器的特性,实际上协程也是基于生成器的(但是无法做到检测IO切换)。所以协程是通过程序自身的控制,去切换不同任务,实现并发的效果。也就是协程是单线程执行,没有多线程由CPU调度时线程切换的开销,所以效率较高。
from gevent import monkey;monkey.patch_all() # 固定编写 用于检测所有的IO操作from gevent import spawnimport timedef play(name):print('%s play 1' % name)time.sleep(1)print('%s play 2' % name)def eat(name):print('%s eat 1' % name)time.sleep(1)print('%s eat 2' % name)start_time = time.time()g1 = spawn(play, 'kevin')g2 = spawn(eat, 'kevin')g1.join() # 等待检测任务执行完毕g2.join() # 等待检测任务执行完毕print('总耗时:', time.time() - start_time) # 正常串行肯定是2S+# 总耗时: 1.001084804534912 代码控制切换
基于协程实现TCP服务端并发
服务端
from gevent import monkey;monkey.patch_all() # 固定编写 用于检测所有的IO操作from gevent import spawnimport socketdef talk(sock):while True:data = sock.recv(1024) # IO操作print(data.encoude('utf8'))sock.send(data.upper())def get_server():IP = '127.0.0.1'PORT = 8080server = socket.socket()server.bind((IP, PORT))server.listen(5)while True:sock, addr = server.accept()spawn(talk, sock)g = spawn(get_server)g.join()
客户端
import socketIP = '127.0.0.1'PORT = 8080client = socket.socket()client.connect((IP, PORT))client.send('hellow world'.encode('utf8'))data = client.recv(1024)print(data.decode('utf8'))
结论
python可以通过开设多进程 在多进程下开设多线程 在多线程使用协程,从而让程序执行的效率达到极致。但是,因为大部分程序都是IO密集型的,实际业务中很少需要如此之高的效率(一直占着CPU不放),了解即可
