文章目录
- gevent 模块
- greenlet 模块
- 示例 - 使用协程单线程实现并发
gevent 模块
from gevent import monkey;monkey.patch_all()
import gevent
import time
import random
# 定义使用协程执行的两个函数
# 间隔随机时间, 打印下一个(模拟 io)
# 因为 io 阻塞时间不同, 所以输出结果也不同
def myprint1(i):
print(i)
time.sleep(random.randint(1,3))
print(i+1)
time.sleep(random.randint(1,3))
print(i+2)
def myprint2():
print("x")
time.sleep(random.randint(1,3))
print("y")
time.sleep(random.randint(1,3))
print("z")
if __name__ == "__main__":
gevent.joinall([
# 参数依次写在 spawn 后边即可
gevent.spawn(myprint1, 10),
gevent.spawn(myprint2),
])
# 等同于
# g1 = gevent.spawn(myprint1, 10)
# g2 = gevent.spawn(myprint2)
# g1.join()
# g2.join()
greenlet 模块
""" - 比较简单粗暴, 声明切换过程 """
import greenlet
def eat(name):
print("%s eat 1" % name)
# No. 2
gp.switch("Tim")
print("%s eat 2" % name)
# No. 4
gp.switch()
def play(name):
print("%s play 1" % name)
# No. 3
ge.switch()
print("%s play 2" % name)
# greenlet 对象
ge = greenlet.greenlet(eat)
gp = greenlet.greenlet(play)
# No. 1
# 第一次使用需要传参, 之后的使用不需要
ge.switch("Tim")
示例 - 使用协程单线程实现并发
- server.py
from gevent import monkey, spawn;monkey.patch_all()
from socket import socket,AF_INET,SOCK_STREAM
from threading import Thread,current_thread
def communicat(conn):
print("子线程: %s" % current_thread().getName())
while True:
try:
data = conn.recv(1024)
if not data:break
conn.send(data.upper())
except ConnectionRefusedError:
break
conn.close()
def server(ip, port):
print("主线程: %s" % current_thread().getName())
s = socket(AF_INET, SOCK_STREAM)
s.bind((ip, port))
s.listen(5)
while 1:
conn, addr = s.accept()
print(addr)
# t = Thread(target=communicat, args=(conn,))
# t.start()
spawn(communicat, conn)
s.close()
if __name__ == "__main__":
g = spawn(server, "127.0.0.1", 8081)
g.join()
- client.py
from socket import socket,AF_INET,SOCK_STREAM
from threading import Thread, current_thread
def client():
c = socket(AF_INET, SOCK_STREAM)
c.connect(("127.0.0.1", 8081))
while 1:
msg = "%s say hello" % current_thread().getName()
c.send(msg.encode("utf-8"))
r = c.recv(1024)
print(r.decode("utf-8"))
c.close()
if __name__ == "__main__":
for i in range(500):
t = Thread(target=client)
t.start()