[英]Release a lock temporarily if it is held, in python
我有一堆不应该同时运行的不同方法,因此我使用一个锁来同步它们。 看起来像这样:
selected_method = choose_method()
with lock:
selected_method()
在这些方法中的某些方法中,有时我会调用一个执行一些缓慢的网络IO的辅助函数。 (让我们调用一个network_method()
)。 我想在此函数运行时释放锁,以允许其他线程继续其处理。
实现此目的的一种方法是在调用网络方法之前和之后调用lock.release()和lock.acquire()。 但是,我宁愿使方法不被锁定,因为它们有很多而且它们随时都在变化。
我更喜欢重写network_method()
以便它检查是否持有该锁,如果是,则在启动之前将其释放,最后再获取它。
请注意,有时会从其他地方调用network_method()
,因此,如果它不在持有该锁的线程上,则不应释放该锁。
我尝试在Lock对象上使用locked()
方法,但是该方法仅告诉我是否持有锁,而不告诉我当前线程是否持有锁。
顺便说一句,锁是一个全局对象,对此我很好。
我更喜欢重写network_method(),以便它检查是否持有该锁,如果是,则在启动之前将其释放,最后再获取它。
请注意,有时会从其他地方调用network_method(),因此,如果它不在持有该锁的线程上,则不应释放该锁。
这听起来完全是错误的事情:(
首先,根据您从何处调用某个函数有时会产生一些其他神奇的副作用是很不好的。 那是调试的噩梦。
其次,锁应具有清晰的获取和释放语义。 如果我看写的代码是“ lock(); do_something(); unlock();” 那么我希望它在do_something()期间被锁定。 实际上,这还告诉我do_something()需要锁定。 如果我发现有人写了一个特定的do_something()可以真正解锁我刚刚看到的锁,我将(a)发射它们或(b)使用武器追捕它们,具体取决于我是否在是否相对于他们有资历。
顺便说一句,锁是一个全局对象,对此我很好。
顺便说一句,这也是为什么全局变量不好的原因。 如果我修改一个值,调用一个函数,然后再次修改一个值,我不希望中间的那个函数能够以一种无法预测的方式伸出援手并修改该值。
我对您的建议是:您的锁在错误的位置,或做错事,或两者兼而有之。 您说这些方法不应该并发运行,但实际上您希望其中一些并发运行。 其中之一“很慢”的事实可能无法使人们满意地删除锁-在这种类型的操作过程中您需要相互排斥才能使锁正确,或者您不需要。 如果较慢的操作在本质上是安全的,而其他操作则不需要,则可能不需要该锁-但这意味着该锁应位于每个较快操作的内部,而不是外部。 但是,所有这些都取决于锁的确切用途。
为什么不这样做呢?
with lock:
before_network()
do_network_stuff()
with lock:
after_network()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.