我已經意識到我的多執行緒程式并沒有像我認為的那樣做。以下是我的策略的 MWE。本質上,我正在創建nThreads執行緒,但實際上只使用其中一個。有人可以幫助我理解我的錯誤以及如何解決它嗎?
import threading
import queue
NPerThread = 100
nThreads = 4
def worker(q: queue.Queue, oq: queue.Queue):
while True:
l = []
threadIData = q.get(block=True)
for i in range(threadIData["N"]):
l.append(f"hello {i} from thread {threading.current_thread().name}")
oq.put(l)
q.task_done()
threadData = [{} for i in range(nThreads)]
inputQ = queue.Queue()
outputQ = queue.Queue()
for threadI in range(nThreads):
threadData[threadI]["thread"] = threading.Thread(
target=worker, args=(inputQ, outputQ),
name=f"WorkerThread{threadI}"
)
threadData[threadI]["N"] = NPerThread
threadData[threadI]["thread"].setDaemon(True)
threadData[threadI]["thread"].start()
for threadI in range(nThreads):
# start and end are in units of 8 bytes.
inputQ.put(threadData[threadI])
inputQ.join()
outData = [None] * nThreads
count = 0
while not outputQ.empty():
outData[count] = outputQ.get()
count = 1
for i in outData:
assert len(i) == NPerThread
print(len(i))
print(outData)
編輯
我只是在分析后才真正意識到我犯了這個錯誤。這是輸出,以供參考:

uj5u.com熱心網友回復:
在您的示例程式中,worker 函式的執行速度非常快,以至于同一個執行緒能夠使每個專案出列。如果你time.sleep(1)給它添加一個呼叫,你會看到其他執行緒接手了一些作業。
但是,重要的是要了解執行緒是否適合您的實際應用程式,這可能是在作業執行緒中執行實際作業。正如@jrbergen 指出的那樣,由于 GIL,一次只有一個執行緒可以執行 Python 位元組碼,所以如果您的作業函式正在執行受 CPU 限制的 Python 代碼(意味著不進行阻塞 I/O 或呼叫釋放 GIL 的庫),您不會從執行緒中獲得性能優勢。在這種情況下,您需要使用流程。
我還要注意,您可能希望使用concurrent.futures.ThreadPoolExecutor或multiprocessing.dummy.ThreadPool用于開箱即用的執行緒池實作,而不是創建自己的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/517397.html
