python异步编程讲解,python io多路复用的优点和缺点
本内容由系统网小编为大家分享,Windows系统安装教程、办公系统、软件怎么使用、软件使用教程、办公软件攻略等信息。
从: 微点阅读 https://ww.Weidianyuedu.com
I/O多路再利用概念:
监视多个描述符的状态,如果描述符的状态发生变化,内核将修改标记,使进程得到读写操作
选择,poll,epoll
选择模块提供了三个方法: select 、 poll 和 epoll,它们分别叫系统 select 、 poll 和 epoll 。
Windows Python:提供:选择
Mac Python:提供:选择
Linux Python: provide: select, poll, epoll
select
在python中,选择函数是直接访问基本操作系统的接口,它用于监控插座、文件和管道,等待IO完成。当发生可读、可写或异常事件时,选择可以轻易地监测。
Select目前支持几乎所有平台,它的良好的跨平台支持是其优点之一,也是其少数剩余的优点之一。
选择的一个缺点是,一个单一进程可以监视的文件描述器数量有最大限度,在Linux上一般是1024,但是这个限度可以通过修改宏来提高。
格式: rList, wList, eList = select.select(argv1,argv2,argv3,timeout)
参数:
argv1:当听序列中的手柄更改时,所更改的手柄被添加到rList序列中
argv2:当听序列包含手柄时,将该序列的所有手柄添加到wList序列中
argv3:当听序列中的手柄产生错误时,所作错误的手柄被添加到eList序列中
timeout:设置阻塞时间,如果不设置,默认总是阻塞
选择实例:
通过选择处理多个接口客户端请求
服务端
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
import select
ip_port = ("127.0.0.1",9999)
Socket = socket.Socket.AF_INET, socket.SOCK_STREAM) # 创建索克对象
sk.bind(ip_port) # bindip,端口
sk.listen(五)
sk.Setblocking (False) #Unblocking
inputs = [sk,]
outputs = []
while True:
rlist,wlist,eList = select.select(inputs,outputs,[],0.5)
print("inputs:",inputs) # 查看输入列表中的更改
打印("rlist:",rlist) # 查看rlist中的更改
for r in rlist:
if r == sk: #if r 是服务结束
conn,address = r.accept()#
inputs.append(conn)
print (address)
else:
client_data = r.recv(1024)
if client_data: # 如果有数据,返回数据
r.sendall(client_data)
其他: # 否则删除
inputs.remove(r)
客户端:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
ip_port = ("127.0.0.1",9999)
索克 = socket.socket() # 创建索克对象
sk.connect(ip_port) #通过ip和端口连接服务器端口
while True:
inpu=input(">>:")
sk.sendall(bytes(inpu, "utf8")) # 向服务器端发送信息
Server_reply = sk.recv(1024) # 收到消息
打印(str(server_reply, "utf8")) #打印消息
sk.close() #关闭连接
过程:
当服务端启动时, 选择将跟踪服务端处理直到客户端请求更改.
当客户端收到新的连接请求时,选择获取服务端手柄中的更改并将更改添加到 rlist中,这样 r == sk 会收到链接并将手柄添加到输入列表中,
现在,选择监视是两个方面。 类似地,当一个以上的链接请求输入时,它被添加到输入列表中。
当其中一个客户端A发送消息时,选择捕捉到所听的客户端A手柄列表中的更改,并将更改的手柄添加到r列表中,但r不等于tosk,
执行另一个步骤操作来接收返回数据.
上面是argv1参数的概览,该参数 listen to the argv1 list, capture it when changes occur, and add it to the rlist。
argv2参数:只要此列表中有一个值,它将每次被添加到wList中,与 argv1不同
所以利用 argv2参数实现读写分离是可能的
server端
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
import select
import queue
ip_port = ("127.0.0.1",9999)
Socket = socket.Socket.AF_INET, socket.SOCK_STREAM) # 创建索克对象
sk.bind(ip_port) # bindip,端口
sk.listen(五)
sk.Setblocking (False) #Unblocking
inputs = [sk,]
outputs = []
message={}
while True:
rlist,wlist,eList = select.select(inputs,outputs,[],0.5)
#print("inputs:",inputs) # 查看输入列表中的更改
#打印("rlist:",rlist) # 查看rlist中的更改
#print(message)
for r in rlist:
if r == sk: #if r 是服务结束
conn,address = r.accept()#
inputs.append(conn) # Listen to the list of inputs for the linked handles
message[conn] = queue.Queue() # 每个新手柄都与一个队列相符
print (address)
else:
client_data = r.recv(1024)
if client_data: # 如果有数据,返回数据
outputs.append(r)
message [r].put(client_data) #将数据插入指定的队列
else:
#否则删除
del message[r] # 删除队列
for w in wlist: #if the wlist list has a value
try:
data =message[w].get_nowait()# 指定取得数据的队列
w.sendall(data)
except queue.Empty:
pass
输出.remove(w) # 由于输出列表每次数据出现时都会添加到wlist中,一旦数据被发送后,数据必须被删除
在 argv3监视列表中,如果在接口连接中发生错误,你可以把错误的手柄添加到eList上,所以在加个判断,当接口连接通信中发生错误时,在列表和词典中删除此错误的连接对象。
在循环中添加判断
for e in eList:
#Remove错误处理器监控输入
如果e在输出中: #如果输出也被删除
outputs.remove(e)
e.close()
del消息 [e] # 删除队列
选择的四个参数被引入后,完整的代码被连接到服务器端
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
import select
import queue
ip_port = ("127.0.0.1",9999)
Socket = socket.Socket.AF_INET, socket.SOCK_STREAM) # 创建索克对象
sk.bind(ip_port) # bindip,端口
sk.listen(五)
sk.Setblocking (False) #Unblocking
inputs = [sk,]
outputs = []
message={}
while True:
rlist,wlist,eList = select.select(inputs,outputs,inputs,0.5)
#print("inputs:",inputs) # 查看输入列表中的更改
#打印("rlist:",rlist) # 查看rlist中的更改
#print(message)
for r in rlist:
if r == sk: #if r 是服务结束
conn,address = r.accept()#
inputs.append(conn) # Listen to the list of inputs for the linked handles
message[conn] = queue.Queue() # 每个新手柄都与一个队列相符
print (address)
else:
client_data = r.recv(1024)
if client_data: # 如果有数据,合同模板将返回数据
outputs.append(r)
message [r].put(client_data) #将数据插入指定的队列
else:
#否则删除
del message[r] # 删除队列
for w in wlist: #if the wlist list has a value
try:
data =message[w].get_nowait()# 指定取得数据的队列
w.sendall(data)
except queue.Empty:
pass
输出.remove(w) # 由于输出列表每次数据出现时都会添加到wlist中,一旦数据被发送后,数据必须被删除
for e in eList:
#Remove错误处理器监控输入
如果e在输出中: #如果输出也被删除
outputs.remove(e)
e.close()
del消息 [e] # 删除队列
XTw.com.Cn系统网专业应用软件下载教程,免费windows10系统,win11,办公软件,OA办公系统,OA软件,办公自动化软件,开源系统,移动办公软件等信息,解决一体化的办公方案。
免责声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。内容仅供参考使用,不准确地方联系删除处理!
联系邮箱:773537036@qq.com