[英]threading.Lock() performance issues
我有多個線程:
dispQ = Queue.Queue()
stop_thr_event = threading.Event()
def worker (stop_event):
while not stop_event.wait(0):
try:
job = dispQ.get(timeout=1)
job.waitcount -= 1
dispQ.task_done()
except Queue.Empty, msg:
continue
# create job objects and put into dispQ here
for j in range(NUM_OF_JOBS):
j = Job()
dispQ.put(j)
# NUM_OF_THREADS could be 10-20 ish
running_threads = []
for t in range(NUM_OF_THREADS):
t1 = threading.Thread( target=worker, args=(stop_thr_event,) )
t1.daemon = True
t1.start()
running_threads.append(t1)
stop_thr_event.set()
for t in running_threads:
t.join()
上面的代碼給了我一些非常奇怪的行為。 我最終發現這是由於等待計數遞減而沒有鎖定
我已經在Job類中添加了一個屬性self.thr_lock = threading.Lock()
然后將其更改為
with job.thr_lock:
job.waitcount -= 1
這似乎可以解決奇怪的問題,但性能似乎有所下降。
這是預期的嗎? 有沒有辦法優化鎖定?
每個作業對象擁有一個全局鎖而不是一個鎖會更好嗎?
根據您的代碼很難回答您的問題。 鎖確實有一些固有的成本,沒有免費的東西,但是通常它很小。 如果您的工作量很小,則可能需要考慮“分塊”它們,這樣相對於每個線程完成的工作量,獲取/釋放調用要少得多。
一個相關但獨立的問題是線程彼此阻塞。 如果許多線程正在等待相同的鎖,則可能會注意到較大的性能問題。 在這里,您的線程處於空閑狀態,彼此等待。 在某些情況下,這是無法避免的,因為存在共享資源,這是性能瓶頸。 在其他情況下,您可以重新組織代碼以避免這種性能損失。
您的示例代碼中有些東西使我覺得它可能與實際應用程序有很大不同。 首先,示例代碼不會在線程之間共享作業對象。 如果您不共享作業對象,則不需要鎖定它們。 其次,按照編寫的示例代碼,可能無法在完成之前清空隊列。 一旦您單擊stop_thr_event.set()
,它將退出,並將任何剩余的作業stop_thr_event.set()
隊列,這是設計stop_thr_event.set()
嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.