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

发布于 2022-09-12 23:37:07 字数 1265 浏览 17 评论 0

我使用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()                           #关闭套接字
#程序显示“已发送”后就陷入死循环

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寂寞清仓 2022-09-19 23:37:07

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

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

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首答,如果有帮助,请点赞支持一下

夜血缘 2022-09-19 23:37:07

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文