【发布时间】:2023-03-17 03:22:01
【问题描述】:
当我的程序遇到断言失败时,我不希望断言库执行导致程序比没有断言失败时更进一步的事情。但这正是内置的assert 似乎在做的事情:它引发了一个异常,从而释放了锁。
例如,考虑以下程序。
import threading
import time
lock = threading.Lock()
class Thread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.start()
def run(self):
with lock:
time.sleep(0.2)
print "ASSERTION ON NEXT LINE"
assert False
# Were it not for the assert,
# This thread would hold the lock for a while longer.
time.sleep(1.0)
Thread()
time.sleep(0.1)
with lock:
print "*** Main Thread ***"
断言导致锁被释放,这导致主线程在断言失败和回溯之间获取锁。结果,输出为:
ASSERTION ON NEXT LINE
*** Main Thread ***
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "so.py", line 14, in run
assert False
AssertionError
这是非常不可取的,因为*** Main Thread *** 是在回溯之前打印的。这很容易让人误以为*** Main Thread *** 在生成异常之前就获得了锁。
我知道我们可以编写自己的断言函数来调用os._exit() 而不是引发断言。我想知道的是标准包中是否已经有类似的东西。
【问题讨论】:
-
不是assert而是上下文管理器
with语句会自动释放锁。 -
您必须区分异常的生成和堆栈跟踪的输出。堆栈跟踪打印在线程中,但主程序继续运行。
-
它是否只是超出了锁定块?
-
@Daniel。是的,它发生了——因为
assert正在释放锁。持有锁的目的应该是停止其他线程运行。 -
没错。 Assert 引发异常,并且上下文管理器在未捕获的异常导致它超出范围时释放锁。您需要要么不生成异常,要么不使用上下文管理器。
标签: python multithreading python-2.7 assertion