[英]How to control the access to a function based on the last access time using threads?
我想根据自上次访问以来经过的时间来控制对函数的访问。
为此,我实现了以下装饰器,它可以在单线程执行中完美运行:
import time
MIN_ELAPSED_TIME = 0.4
time_last_get = time.time()
def timingRequests(f):
def wrapper(*args, **kwargs):
global time_last_get
elapsed_time_since_last_get = time.time() - time_last_get
if elapsed_time_last_request < MIN_REQUEST_TIME: # not enough time has passed since the last request
time.sleep(MIN_REQUEST_TIME - elapsed_time_last_request)
# At this point, at least MIN_ELAPSED_TIME has passed since last get
time_last_get = time.time()
r = f(*args, **kwargs)
return r
return wrapper
@timingRequests
doGet()
我想让 n 个线程(现在 2 个)访问这个函数并考虑线程之间的 time_last_get。 我的问题是每个线程都在等待根据自己之前执行的 doGet() 执行 doGet()
我尝试使用 threading.Event() 作为信号量, threading.Lock() 但仍然两个线程几乎同时访问该函数。
使用 2 个或更多线程时的行为是每个线程都根据同一线程的 time_last_get 等待执行 doGet(),而不是考虑其他线程的访问。
我想要实现的行为是下一个:
线程 1:doGet()
线程 2:等待(如有必要)自线程 2 访问以来经过的 MIN_ELAPSED_TIME 秒
线程 2:doGet()
线程 1:等待(如有必要)自线程 2 访问以来经过的 MIN_ELAPSED_TIME 秒
线程 1:doGet()
线程 1:等待(如有必要)自线程 1 访问以来经过的 MIN_ELAPSED_TIME 秒
我想通了是什么问题。
首先,我确实通过使用 threading.Events() 实例绕过了这个问题:
import time
MIN_ELAPSED_TIME = 0.4
time_last_get = time.time()
e = threading.Event()
e.set()
def timingRequests(f):
def wrapper(*args, **kwargs):
e.wait()
e.clear()
global time_last_get
elapsed_time_since_last_get = time.time() - time_last_get
if elapsed_time_last_request < MIN_REQUEST_TIME: # not enough time has passed since the last request
time.sleep(MIN_REQUEST_TIME - elapsed_time_last_request)
# At this point, at least MIN_ELAPSED_TIME has passed since last get
time_last_get = time.time()
r = f(*args, **kwargs)
e.set()
return r
return wrapper
@timingRequests
doGet()
但是我仍然很难理解为什么这个解决方案有效,但没有使用锁。
嗯,问题是这样的:
def timingRequests(f):
def wrapper(*args, **kwargs):
with threading.Lock():
# Code
到达这部分代码的每个线程都在创建一个(未锁定的)threading.Lock() 实例,因此锁没有按预期工作。 然后解决方案是在timingRequests函数之外创建锁并以这种方式使用它:
lock = threading.Lock()
def timingRequests(f):
def wrapper(*args, **kwargs):
with lock:
# Code
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.