协程
协程的作用就是在执行某个子程序(函数)时,可以指定或者随机地中断,然后去执行其他的子程序(函数),在合适的时候再返回到中断子程序停止时的状态继续执行。听起像生成器的特性,实际上协程也是基于生成器的(但是无法做到检测IO切换)。所以协程是通过程序自身的控制,去切换不同任务,实现并发的效果。也就是协程是单线程执行,没有多线程由CPU调度时线程切换的开销,所以效率较高。
from gevent import monkey;monkey.patch_all() # 固定编写 用于检测所有的IO操作
from gevent import spawn
import time
def 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 spawn
import socket
def 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 = 8080
server = 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 socket
IP = '127.0.0.1'
PORT = 8080
client = socket.socket()
client.connect((IP, PORT))
client.send('hellow world'.encode('utf8'))
data = client.recv(1024)
print(data.decode('utf8'))
结论
python可以通过开设多进程 在多进程下开设多线程 在多线程使用协程,从而让程序执行的效率达到极致。但是,因为大部分程序都是IO密集型的,实际业务中很少需要如此之高的效率(一直占着CPU不放),了解即可