协程(微线程)
协程分两种,一种是greenlet,需要手动切换,另一种是gevent,不需手动切换,自动切换
例如1:
from greenlet import greenlet //这里如果用 import greenlet 会出错 def test_1(): print('running test_1 first!') gr2.switch() print('running test_2 second!!') gr2.switch() def test_2(): print('running test_2 first!') gr1.switch() print('running test_2 second!') if __name__ == '__main__': gr1 = greenlet(test_1) gr2 = greenlet(test_2) gr1.switch() //如果没有这一步程序不会运行,gr1、gr2只是生成两个协程,gr1.switch()是切换到gr1这个协程里边,然后开始运行的运行结果如下::
running test_1 first!
running test_2 first!
running test_2 second!!
running test_2 second!
例2:gevent是当协程遇到I/O(不占用CPU资源时)就自动切换到下一个协程
运行的结果如下:
Runing in foo
Explicit context to bar
running func3
running func3 again
Implicit context switch back to bar
Explicit context switch to foo again
2、协程下的多并发
import sys import socket import time import gevent from gevent import socket,monkey //导入monkey模块和下边的monkey.patch_all()方法,gevent就能检测到I/O端口,就能实现自动切换,意义上的多并发,其实只是在串行程序中切换。。 monkey.patch_all() def server(port): s = socket.socket() s.bind(('0.0.0.0', port)) s.listen(500) while True: cli, addr = s.accept() gevent.spawn(handle_request, cli) def handle_request(conn): try: while True: data = conn.recv(1024) print("recv:", data) conn.send(data) if not data: conn.shutdown(socket.SHUT_WR) except Exception as ex: print(ex) finally: conn.close() if __name__ == '__main__': server(8001)
import socket HOST = 'localhost' # The remote host PORT = 8001 # The same port as used by the server s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST, PORT)) while True: msg = bytes(input(">>:"), encoding="utf8") s.sendall(msg) data = s.recv(1024) # print(data) print('Received', data.upper()) s.close()