gpt4 book ai didi

python - 运行 Python 延迟循环的最不痛苦的方法

转载 作者:行者123 更新时间:2023-11-28 19:51:00 24 4
gpt4 key购买 nike

我有一个事件驱动的聊天机器人,我正在尝试实现垃圾邮件防护。我想在一段时间内让行为不端的用户保持沉默,而不阻塞应用程序的其余部分。

这是不起作用的:

if user_behaving_badly():
ban( user )
time.sleep( penalty_duration ) # Bad! Blocks the entire application!
unban( user )

理想情况下,如果 user_behaving_badly() 为真,我想启动一个新线程,该线程除了禁止用户外什么都不做,然后休眠一段时间,取消禁止用户,然后线程消失。

According to this我可以使用以下方法实现我的目标:

if user_behaving_badly():
thread.start_new_thread( banSleepUnban, ( user, penalty ) )

“简单”通常表示“好”,这很简单,但我所听说的关于线程的一切都表明它们可以以意想不到的方式咬住你。我的问题是:有没有比这更好的方法来运行一个简单的延迟循环而不阻塞应用程序的其余部分?

最佳答案

不是为每个禁令启动一个线程,而是将禁令放在一个优先级队列中,让一个线程进行休眠和解除禁令

这段代码保留了两个结构,一个是 heapq,允许它快速找到最快的禁令过期,另一个是 dict,可以快速检查用户是否被名字禁止

import time
import threading
import heapq

class Bans():
def __init__(self):
self.lock = threading.Lock()
self.event = threading.Event()
self.heap = []
self.dict = {}
self.thread = threading.thread(target=self.expiration_thread)
self.thread.setDaemon(True)
self.thread.start()

def ban_user(self, name, duration):
with self.lock:
now = time.time()
expiration = (now+duration)
heapq.heappush(self.heap, (expiration, user))
self.dict[user] = expiration
self.event.set()

def is_user_banned(self, user):
with self.lock:
now = time.time()
return self.dict.get(user, None) > now

def expiration_thread(self):
while True:
self.event.wait()
with self.lock:
next, user = self.heap[0]
now = time.time()
duration = next-now
if duration > 0:
time.sleep(duration)
with self.lock:
if self.heap[0][0] = next:
heapq.heappop(self.heap)
del self.dict(user)
if not self.heap:
self.event.clear()

像这样使用:

B = Bans()
B.ban_user("phil", 30.0)
B.is_user_banned("phil")

关于python - 运行 Python 延迟循环的最不痛苦的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7775251/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com