Python使用eventlet包超时检测出现了问题?

Python使用eventlet包超时检测出现了问题?

我使用eventlet包进行代码的超时检测,但是检测的内容不同,怎么结果就不同呢??

text1.py

import eventlet,time          #导入该包和time模块

eventlet.monkey_patch() #猴子补丁

t = 1 #设置超时时间为1秒

#这行语句下的语句块是超时检测的内容

with eventlet.Timeout(t,False): #第一个参数:超时时间,超过该时间则执行后面的语句

time.sleep(3) #程序挂起3秒

print("OK!") #如果没有超时,则输出提示“OK!”

print("Time Out!") #如果超时则输出提示“Time Out!”

#程序等待1秒后输出:Time Out!

text2.py

import eventlet,socket              #导入该包和socket模块

s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #建立UDP连接

s.sendto("Hello Python".encode(),("33.33.33.33",8888)) #试图向无效IP(33.33.33.33:8888)发送消息“Hello Python”

print("已发送") #发送后输出提示

eventlet.monkey_patch() #猴子补丁

t = 1 #设置超时时间为1秒

with eventlet.Timeout(t,False): #第一个参数:超时时间,超过该时间则执行后面的语句

data,addr = s.recvfrom(1024) #接收消息

if data: #如果接收到了消息则输出提示

print("接收到了消息!")

print(data.decode())

s.close() #关闭套接字

print("没有接收到消息!") #如果超时则输出“没有接收到消息!”

s.close() #关闭套接字

#程序显示“已发送”后就陷入死循环

请问各位大佬,这是怎么回事?在线等,急!


回答:

1.如果仅仅是为了在网络通讯的是进行超时控制

我也比较认同使用timeout控制,比如

python">import socket

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 建立UDP连接s

s.settimeout(1) # <------------------ 1秒内无法完成通讯抛超时异常

s.sendto("Hello Python".encode(), ("33.33.33.33", 8888))

try:

data, addr = s.recvfrom(1024) # 接收消息

print(data)

except socket.timeout: # 超时会引发异常

print("没有接收到消息!") # 如果超时则输出“没有接收到消息!”

2. 如果是为了搞清楚text2.py为何无效

2.1. 首先,eventlet是一个协程库

用来实现和管理协程,使得网络通讯具有更高的并发,从这个角度讲,你选择eventlet进行网络超时在控制没毛病

2.2. 那么,eventlet是如何做到这一点呢?

首先通过猴子补丁替修改python原本的底层模块,使之支持切换调度,然后再用eventlet进行管理。
划重点,先通过猴子补丁替修改python原本的底层模块,这是eventlet正常工作的前提。
再来回顾一下text2.py的代码

import eventlet,socket             

s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #socket实例已创建

s.sendto("Hello Python".encode(),("33.33.33.33",8888))

eventlet.monkey_patch() #再用猴子补丁

思考一个问题:

猴子补丁修改某个类,会有已有的实例对象有响应吗?

如果有兴趣的话,我们新开一个帖子聊这个问题,
现在,我们先解决问题: 猴子补丁在前,创建socket在后

修改之后,控制超时成功的例子:

import socket

import eventlet

# 代码第一件事情,使用猴子补丁,其他地方不变

eventlet.monkey_patch()

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 建立UDP连接

s.sendto(

"Hello Python".encode(), ("33.33.33.33", 8888)

) # 试图向无效IP(33.33.33.33:8888)发送消息“Hello Python”

print("已发送") # 发送后输出提示

t = 1 # 设置超时时间为1秒

with eventlet.Timeout(t, False): # 第一个参数:超时时间,超过该时间则执行后面的语句

data, addr = s.recvfrom(1024) # 接收消息

if data: # 如果接收到了消息则输出提示

print("接收到了消息!")

print(data.decode())

s.close() # 关闭套接字

print("没有接收到消息!") # 如果超时则输出“没有接收到消息!”

s.close() # 关闭套接字

segmentfault首答,如果有帮助,请点赞支持一下


回答:

不用这么麻烦吧,s.setsockopt可以设置socket客户端接受消息的超时时间

以上是 Python使用eventlet包超时检测出现了问题? 的全部内容, 来源链接: utcz.com/a/162103.html

回到顶部