Engineering · 1 min read
Python with lock:例外發生時也保證釋放鎖
手動 acquire 與 release 少了 try/finally,一次例外就會讓鎖永遠不放。Python 的 with lock 語法糖能保證例外時鎖依然釋放。
多執行緒下的 Python
with lock: 保證例外時也會釋放鎖
手動 acquire()/release() 少了 try/finally,body 一拋錯,鎖就永遠不放——之後每個取鎖者都卡住,變成永久死鎖。
with lock: 其實是 acquire + try/finally release 的語法糖:
with self._login_lock: # lock.acquire()
... # try: ... finally: lock.release()
區塊結束時 release() 一定會執行——連 body 拋例外時也是。
真實情境:login() 的臨界區呼叫 session.post() + raise_for_status(),兩者都可能拋錯。用 with self._login_lock: 就能確保網路錯誤時鎖會釋放,避免一次失敗的登入卡死該 worker 後續所有登入。
Python threading library 的同步原語全都支援 with:Lock、RLock、Condition、Semaphore、BoundedSemaphore。能用 with 就用。
鎖的釋放不該依賴 happy path。用
with,把它交給finally。
參考來源:
- https://docs.python.org/3/library/threading.html
- https://superfastpython.com/thread-context-manager/
Related: 參見雙重檢查鎖定的兩個檢查各司其職拆解、先做完再發佈的安全發佈模式,或回到讓 login 執行緒安全的四筆學費總覽。