您现在的位置是:首页» windows系统» python异步编程讲解,python io多路复用的优点和缺点

python异步编程讲解,python io多路复用的优点和缺点

2024-07-13 13:52:50
本内容由系统网小编为大家分享,Windows系统安装教程、办公系统、软件怎么使用、软件使用教程、办公软件攻略等信息。 从: 微点阅读 https://ww.Weidianyuedu.com I/O多路再利用概念:监视多个描述符的状态,如果

本内容由系统网小编为大家分享,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

标签: 多路 复用 概念