单线程之间的并发就是利用一个线程实现并发的效果,也就是利用了cup遇到阻塞的那段时间去做别的事情,从而提高了cup的利用率,使之在单个线程中就实现了并发的效果。
下面就是一个简单的服务端单个线程实现并发的代码:
from socket import *
server=socket(AF_INET,SOCK_STREAM)
server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)#地址重用
server.bind(('127.0.0.1',8082)) #绑定端口
server.listen(5)#监听
server.setblocking(False)#关闭IO阻塞
print('Starting......')
conn_l=[]
del_l=[]
while True:
try:
conn,addr=server.accept()#建立连接
print('%s 已连接'%addr[0])
conn_l.append(conn)
except BlockingIOError:#捕捉IO阻塞异常
for conn in conn_l:
try:
data=conn.recv(1024)#接受数据
conn.send(data.upper())
except BlockingIOError:
pass
except ConnectionResetError:#捕捉主机强行断开异常
del_l.append(conn) #存到列表准备删除断开的连接
for obj in del_l:
obj.close() #关闭连接
conn_l.remove(obj) #删除连接
del_l=[] #清空
很明显,这种方式太麻烦,要自己捕获异常的信号去进行相应的处理。
这个时候就应该想到python模块了,没错selete这个模块就可以做这些捕捉信息的功能。
下面就用selete模块来写上面那些代码吧:
from socket import *
import select
server=socket(AF_INET,SOCK_STREAM)
server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
server.bind(('127.0.0.1',8082))
server.listen(5)
server.setblocking(False)
print('Starting......')
read_l=[server,]
while True:
s,_,_=select.select(read_l,[],[])
for obj in s :
if obj == server:
conn, addr = obj.accept()
read_l.append(conn)
else:
try:
data=obj.recv(1024)
obj.send(data.upper())
except ConnectionResetError:
pass
很明显,要比上面代码精简好多,这就是Python模块的好处了,哈哈 ....