Nó sắp hết thời gian. Windows cần tạo ra 4 quy trình trong Pool
, sau đó cần khởi động, khởi tạo và chuẩn bị để tiêu thụ từ Queue
. Trên Windows, điều này đòi hỏi mỗi quy trình con phải nhập lại mô-đun __main__
và đối với các trường hợp Queue
được sử dụng nội bộ theo số Pool
để được bỏ tạm dừng ở mỗi trẻ. Việc này mất một lượng thời gian không nhỏ. Đủ lâu, trên thực tế, khi cả hai cuộc gọi map_async()
của bạn được thực thi trước khi tất cả các quy trình trong Pool
đều được thiết lập và hoạt động. Bạn có thể thấy điều này nếu bạn thêm một số lần theo các chức năng chạy bởi mỗi công nhân trong Pool
:
while maxtasks is None or (maxtasks and completed < maxtasks):
try:
print("getting {}".format(current_process()))
task = get() # This is getting the task from the parent process
print("got {}".format(current_process()))
Output:
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
process id = 5145
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
process id = 5145
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
result = [121]
result1 = [100]
getting <ForkServerProcess(ForkServerPoolWorker-2, started daemon)>
getting <ForkServerProcess(ForkServerPoolWorker-3, started daemon)>
getting <ForkServerProcess(ForkServerPoolWorker-4, started daemon)>
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
Như bạn thấy, Worker-1
bắt đầu lên và tiêu thụ cả nhiệm vụ trước khi người lao động 2-4 bao giờ cố gắng tiêu thụ từ Queue
. Nếu bạn thêm một cuộc gọi sleep
sau khi bạn nhanh chóng Pool
trong quá trình chính, nhưng trước khi gọi map_async
, bạn sẽ thấy quá trình khác nhau xử lý mỗi yêu cầu:
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
getting <ForkServerProcess(ForkServerPoolWorker-2, started daemon)>
getting <ForkServerProcess(ForkServerPoolWorker-3, started daemon)>
getting <ForkServerProcess(ForkServerPoolWorker-4, started daemon)>
# <sleeping here>
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
process id = 5183
got <ForkServerProcess(ForkServerPoolWorker-2, started daemon)>
process id = 5184
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
getting <ForkServerProcess(ForkServerPoolWorker-2, started daemon)>
result = [121]
result1 = [100]
got <ForkServerProcess(ForkServerPoolWorker-3, started daemon)>
got <ForkServerProcess(ForkServerPoolWorker-4, started daemon)>
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
got <ForkServerProcess(ForkServerPoolWorker-2, started daemon)>
(Lưu ý rằng thêm "getting
/"got"
báo cáo mà bạn nhìn thấy là các sentinels được gửi đến từng quá trình để đóng chúng một cách duyên dáng).
Sử dụng Python 3.x trên Linux, tôi có thể tạo lại hành vi này bằng các ngữ cảnh 'spawn'
và 'forkserver'
, nhưng không phải 'fork'
. Có lẽ bởi vì forking các tiến trình con nhanh hơn nhiều so với sinh sản chúng và làm một tái nhập khẩu của __main__
.
Bạn đang sử dụng Windows? – dano
@ dano-yes ....., – user1050619