import threading
import weakref
_mainlock = threading.RLock()
_job_locks = weakref.WeakValueDictionary()
def do_thing(job_id):
_mainlock.acquire() #Dictionary modification lock acquire
_job_locks.setdefault(job_id, threading.RLock()) #Possibly modifies the dictionary
_mainlock.release()
_job_locks[job_id].acquire()
try:
one_time_init(job_id)
finally:
_job_locks[job_id].release()
#On function return, the weakref.WeakValueDictionary should cause the key to evaporate
do_thing() が同じかどうかわからない ID 番号を持つ多くのスレッドで何度も呼び出されると仮定すると (たとえば、ID 3 で 4 回、異なる ID でそれぞれ 1 回)、このスレッドは安全ですか? one_time_init() は、特定のジョブ ID に対して一度に複数回実行されることはありますか? (PS: one_time_init は、ID ごとに 1 回実行された状態を保存するため、既に完了まで実行されている場合、呼び出しはノーオペレーションです)
更新されたコード (THC4k に感謝):
import threading
import weakref
_mainlock = threading.RLock()
_job_locks = weakref.WeakValueDictionary()
def do_thing(job_id):
with _mainlock:
jl = _job_locks.setdefault(job_id, threading.RLock())
with jl:
one_time_init(job_id)