我有多個multiprocessing.Process()獲取和發布:
s = Semaphore(5)
是否s.acquire()保證按順序完成呼叫?
如果沒有,我可以使用什么代替,以便第一個請求行程首先訪問資源?
uj5u.com熱心網友回復:
根據threading.Semaphore.acquire檔案:
如果內部計數器在進入時大于零,則將其減一并立即回傳 True。
如果內部計數器在進入時為零,則阻塞直到被呼叫 release() 喚醒。一旦喚醒(并且計數器大于 0),將計數器減 1 并回傳 True。每次呼叫 release() 都會喚醒一個執行緒。不應依賴執行緒被喚醒的順序。
(強調我的)
換句話說,當您的信號量尚未達到零時,呼叫將立即成功。然后,所有呼叫都將阻塞,直到呼叫一個release。此時,任何執行緒都可以從其acquire.
這是一個最小的可重現示例:
import threading
NB_TOTAL = 20
NB_SHARED = 5
sem = threading.Semaphore(5)
def acquire_semaphore_then_do_something(thread_number: int):
sem.acquire()
do_something(thread_number)
sem.release()
def do_something(number: int):
print(number)
# create the threads
threads = [threading.Thread(target=acquire_semaphore_then_do_something, args=(thread_number,))
for thread_number in range(NB_TOTAL)]
# start them all
for thread in threads:
thread.start()
# wait for all of them to finish
for thread in threads:
thread.join()
如果您真的需要執行緒完全按照它們的創建順序運行,我建議您以不同的方式處理事情:
import threading
NB_TOTAL = 20
NB_SHARED = 5
THREAD_LOCKS = [threading.Lock() for _ in range(NB_TOTAL)]
LOCKS_LOCK = threading.Lock() # lock for the locks management
NEXT_UNLOCK_INDEX = NB_SHARED
def acquire_sequentially_then_do_something(thread_number: int):
# try to acquire the dedicated lock
THREAD_LOCKS[thread_number].acquire() # blocking
# dedicated lock acquired, proceeding
do_something(thread_number)
# now it has finished its work, it can unlock the next thread
global NEXT_UNLOCK_INDEX
if NEXT_UNLOCK_INDEX < NB_TOTAL:
with LOCKS_LOCK:
THREAD_LOCKS[NEXT_UNLOCK_INDEX].release()
NEXT_UNLOCK_INDEX = 1
def do_something(number: int):
print(number)
# lock all the locks, except the NB_SHARED first : indexes from 0 to NB_SHARED-1
for number, lock in enumerate(THREAD_LOCKS):
if number >= NB_SHARED:
assert lock.acquire(blocking=False)
# create the threads
threads = [threading.Thread(target=acquire_sequentially_then_do_something, args=(thread_number,))
for thread_number in range(NB_TOTAL)]
# start them all
for thread in threads:
thread.start()
# wait for all of them to finish
for thread in threads:
thread.join()
正確列印
0
1
2
[...]
17
18
19
思路是NEXT_UNLOCK_INDEX,每次都將特定的鎖加1加1,讓對應的執行緒最終可以鎖定它并繼續進行。它確保執行緒遵守“先到先得”的原則。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/403028.html
標籤:
上一篇:Quarkus與休眠發現[bpchar(Types#CHAR)],但期待[char(Types#VARCHAR)]
