week10-IO模型
阻塞IO客户端
from socket import * client=socket(AF_INET,SOCK_STREAM) client.connect(('127.0.0.1',8080)) while True: msg=input('>>: ').strip() if not msg:continue client.send(msg.encode('utf-8')) data=client.recv(1024) print(data.decode('utf-8'))
阻塞IO服务端
from socket import * server=socket(AF_INET,SOCK_STREAM) server.bind(('127.0.0.1',8080)) server.listen(5) while True: conn,addr=server.accept() print(addr) while True: try: data=conn.recv(1024) if not data:break conn.send(data.upper()) except Exception: break conn.close() server.close()
非阻塞IO客户端
from socket import * client=socket(AF_INET,SOCK_STREAM) client.connect(('127.0.0.1',8080)) while True: msg=input('>>: ').strip() if not msg:continue client.send(msg.encode('utf-8')) data=client.recv(1024) print(data.decode('utf-8'))
非阻塞服务器端
from socket import * import time server=socket(AF_INET,SOCK_STREAM) server.bind(('127.0.0.1',8080)) server.listen(5) server.setblocking(False) conns=[] del_l=[] while True: try: print(conns) conn,addr=server.accept() conns.append(conn) except BlockingIOError: for conn in conns: try: data=conn.recv(1024) conn.send(data.upper()) except BlockingIOError: pass except ConnectionResetError: conn.close() del_l.append(conn) for conn in del_l: conns.remove(conn) del_l=[]
IO多路复用客户端
from socket import * client=socket(AF_INET,SOCK_STREAM) client.connect(('127.0.0.1',8080)) while True: msg=input('>>: ').strip() if not msg:continue client.send(msg.encode('utf-8')) data=client.recv(1024) print(data.decode('utf-8'))
IO多路复用服务端
from socket import * import select import time server=socket(AF_INET,SOCK_STREAM) server.bind(('127.0.0.1',8080)) server.listen(5) server.setblocking(False) reads=[server,] while True: rl,_,_=select.select(reads,[],[]) for obj in rl: if obj == server: conn,addr=obj.accept() reads.append(conn) else: try: data=obj.recv(1024) if not data: obj.close() reads.remove(obj) continue obj.send(data.upper()) except Exception: obj.close() reads.remove(obj)
基于yield实现并发
import time def consumer(): while True: res=yield def producer(): g=consumer() next(g) for i in range(100000000): g.send(i) start=time.time() producer() print(time.time()-start) #12.602720737457275 import time def consumer(res): print('consumer') def producer(): res=[] for i in range(100000000): res.append(i) return res start=time.time() res=producer() consumer(res) print(time.time()-start) #12.344706058502197 import time def consumer(): while True: res=yield print('consumer',res) time.sleep(10) def producer(): g=consumer() next(g) for i in range(100000000): print('producer', i) g.send(i) start=time.time() producer() print(time.time()-start) #12.602720737457275
greenlet模块
from greenlet import greenlet import time def eat(name): print('%s eat 1' %name) g2.switch('egon') # print('%s eat 2' %name) g2.switch() def play(name): print('%s play 1' %name) time.sleep(10) g1.switch() print('%s play 2' %name) g1=greenlet(eat) g2=greenlet(play) g1.switch('egon')
gevent模块
from gevent import monkey;monkey.patch_all() import gevent import time import threading def eat(name): print(threading.current_thread().getName()) print('%s eat 1' %name) time.sleep(1) print('%s eat 2' %name) def play(name): print(threading.current_thread().getName()) print('%s play 1' %name) time.sleep(2) print('%s play 2' %name) g1=gevent.spawn(eat,'egon') g2=gevent.spawn(play,'egon') # g1.join() # g2.join() gevent.joinall([g1,g2])
gevent客户端
#_*_coding:utf-8_*_ from threading import Thread from socket import * def client(): client=socket(AF_INET,SOCK_STREAM) client.connect(('127.0.0.1',8080)) while True: client.send('hello'.encode('utf-8')) msg=client.recv(1024) print(msg.decode('utf-8')) if __name__ == '__main__': for i in range(500): t=Thread(target=client) t.start()
gevent服务器端
from gevent import monkey;monkey.patch_all() from socket import * import gevent #如果不想用money.patch_all()打补丁,可以用gevent自带的socket # from gevent import socket # s=socket.socket() def server(server_ip,port): s=socket(AF_INET,SOCK_STREAM) s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) s.bind((server_ip,port)) s.listen(5) while True: conn,addr=s.accept() gevent.spawn(talk,conn,addr) def talk(conn,addr): try: while True: res=conn.recv(1024) print('client %s:%s msg: %s' %(addr[0],addr[1],res)) conn.send(res.upper()) except Exception as e: print(e) finally: conn.close() if __name__ == '__main__': server('127.0.0.1',8080)
参考链接:
异步IO\数据库\队列\缓存
http://www.cnblogs.com/alex3714/articles/5248247.html
sellect、poll、epoll三者的区别
http://www.cnblogs.com/alex3714/p/4372426.html
IO多路复用
http://www.cnblogs.com/alex3714/articles/5876749.html
Cpython解释器支持的进程与线程
http://www.cnblogs.com/linhaifeng/articles/6817679.html
python并发编程之IO模型
http://www.cnblogs.com/linhaifeng/articles/7454717.html
志不强者智不达
浙公网安备 33010602011771号