在運行我的代碼時,“柜員”執行緒一遍又一遍地幫助同一個“客戶”執行緒,直到不確定的次數。我不明白為什么盡管創建了其他執行緒,但創建的最后一個客戶卻一遍又一遍地得到幫助。
我不確定客戶執行緒的代碼中某處是否需要 .join() 。我已將它放在代碼中的多個位置,我的代碼似乎卡住了。
from threading import Semaphore, Thread, Lock
from queue import Queue, Empty
from random import randint
from time import sleep
max_customers_in_bank = 10
'''maximum number of customers that can be in
the bank at one time'''
max_customers = 7 # number of customers that will go to the bank today
max_tellers = 2 # number of tellers working today
teller_timeout = 10 # longest time that a teller will wait for new customers
# Part I
class Customer:
def __init__(self, name):
self.name = name
def __str__(self):
return {self.name}
class Teller:
def __init__(self, name):
self.name = name
def __str__(self):
return {self.name}
def bankprint(lock, msg):
# Print message with a context manager lock
with lock:
print(msg)
def wait_outside_bank(customer, guard, teller_line, printlock):
# Call bankprint and format customer object string approiately for call
bankprint(printlock, ("(C) '" customer.name "' waiting outside bank"))
# Create semphore for max customers and aquire it
guard.acquire()
bankprint(printlock,
("<G> Security guard letting '"
customer.name "' into the bank"))
bankprint(printlock, ("(C) '" customer.name "' getting into line"))
# Create teller line queue and put custiomers into queue
teller_line.put(customer)
# Part III
def teller_job(teller, guard, teller_line, printlock):
bankprint(printlock, ("[T] '" teller.name "' starting work"))
while True:
try:
teller_line.get(timeout=teller_timeout)
bankprint(printlock, ("[T] '" teller.name "' is now helping"
customer.name))
sleep(randint(1, 4))
bankprint(printlock, ("[T] '" teller.name "' is done helping"
customer.name))
bankprint(printlock, ("<G> Security guard letting '"
customer.name "' out of the bank"))
guard.release()
except Empty:
bankprint(printlock, ("[T] Nobody is in line, '" teller.name
"' is going on break"))
break
if __name__ == "__main__":
printlock = Lock()
teller_line = Queue(maxsize=max_customers_in_bank)
guard = Semaphore(max_customers_in_bank)
Customer_List = [Customer("Customer_" str(i)) for i in
range(1, max_customers 1)]
for customer in Customer_List:
thread = Thread(target=wait_outside_bank,
args=(customer, guard, teller_line, printlock))
thread.start()
sleep(5)
print("*B* Tellers starting work")
Teller_List = [Teller("Teller_" str(i)) for i in range(1, max_tellers 1)]
Teller_Threads = [Thread(target = teller_job, args = (teller, guard, teller_line, printlock)) for teller in Teller_List]
for teller in Teller_Threads:
teller.start()
for teller in Teller_Threads:
teller.join()
print("*B* Bank closed")
樣本輸出:
(C) 'Customer_1' waiting outside bank
<G> Security guard letting 'Customer_1' into the bank
(C) 'Customer_1' getting into line
(C) 'Customer_2' waiting outside bank
(C) 'Customer_3' waiting outside bank
<G> Security guard letting 'Customer_2' into the bank
(C) 'Customer_4' waiting outside bank
<G> Security guard letting 'Customer_3' into the bank
(C) 'Customer_3' getting into line
(C) 'Customer_2' getting into line
(C) 'Customer_6' waiting outside bank
<G> Security guard letting 'Customer_4' into the bank
(C) 'Customer_4' getting into line
(C) 'Customer_7' waiting outside bank
<G> Security guard letting 'Customer_6' into the bank
(C) 'Customer_5' waiting outside bank
<G> Security guard letting 'Customer_7' into the bank
(C) 'Customer_7' getting into line
<G> Security guard letting 'Customer_5' into the bank
(C) 'Customer_5' getting into line
(C) 'Customer_6' getting into line
*B* Tellers starting work
[T] 'Teller_1' starting work
[T] 'Teller_1' is now helpingCustomer_7
[T] 'Teller_2' starting work
[T] 'Teller_2' is now helpingCustomer_7
[T] 'Teller_1' is done helpingCustomer_7
<G> Security guard letting 'Customer_7' out of the bank
[T] 'Teller_1' is now helpingCustomer_7
[T] 'Teller_2' is done helpingCustomer_7
<G> Security guard letting 'Customer_7' out of the bank
[T] 'Teller_2' is now helpingCustomer_7
[T] 'Teller_1' is done helpingCustomer_7
[T] 'Teller_2' is done helpingCustomer_7
<G> Security guard letting 'Customer_7' out of the bank
<G> Security guard letting 'Customer_7' out of the bank
[T] 'Teller_1' is now helpingCustomer_7
[T] 'Teller_2' is now helpingCustomer_7
[T] 'Teller_1' is done helpingCustomer_7
<G> Security guard letting 'Customer_7' out of the bank
[T] 'Teller_1' is now helpingCustomer_7
[T] 'Teller_2' is done helpingCustomer_7
<G> Security guard letting 'Customer_7' out of the bank
[T] 'Teller_1' is done helpingCustomer_7
<G> Security guard letting 'Customer_7' out of the bank
[T] Nobody is in line, 'Teller_2' is going on break
[T] Nobody is in line, 'Teller_1' is going on break
*B* Bank closed
uj5u.com熱心網友回復:
teller_job沒有定義customer所以當你使用時customer.name,你customer在全域命名空間中使用。它是在 for 回圈中分配的,for customer in Customer_List:并且在執行緒進行處理之前,該回圈已經完成(將串列中的最后一個客戶保留為最后一個值)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/429531.html
標籤:Python 多线程 队列 python-多线程
上一篇:如何在Python中將csv檔案的一列轉換為txt檔案?
下一篇:物件轉換期間執行緒“主”錯誤中的例外[java.lang.ClassCastException]-如何解決轉換問題?
