Lớp nhóm đa xử lý Python cho phép bạn tạo và quản lý các nhóm quy trình trong Python.Python Multiprocessing Pool class allows you to create and manage process pools in Python. Show
Mặc dù nhóm đa xử lý đã có sẵn trong Python trong một thời gian dài, nhưng nó không được sử dụng rộng rãi, có lẽ vì những hiểu lầm về khả năng và hạn chế của các quy trình và luồng trong Python.Multiprocessing Pool has been available in Python for a long time, it is not widely used, perhaps because of misunderstandings of the capabilities and limitations of Processes and Threads in Python. Hướng dẫn này cung cấp một đánh giá chi tiết và toàn diện về nhóm Themultiprocessing trong Python, bao gồm cách thức hoạt động, cách sử dụng nó, các câu hỏi phổ biến và thực tiễn tốt nhất.Multiprocessing Pool in Python, including how it works, how to use it, common questions, and best practices. Đây là một hướng dẫn lớn hơn 26.000 từ. Bạn có thể muốn đánh dấu nó để bạn có thể tham khảo nó khi bạn phát triển các chương trình đồng thời của mình. Hãy để lặn trong.
Các quy trình của Python và nhu cầu về các nhóm quy trìnhVì vậy, các quy trình là gì và tại sao chúng ta quan tâm đến nhóm quy trình? Quá trình Python là gìMột quy trình đề cập đến một chương trình máy tính. Mỗi chương trình Python là một quy trình và có một luồng được gọi là luồng chính được sử dụng để thực hiện các hướng dẫn chương trình của bạn. Trên thực tế, mỗi quá trình là một trường hợp của trình thông dịch Python thực thi các hướng dẫn Python (mã byte Python), mức thấp hơn một chút so với mã bạn nhập vào chương trình Python của bạn. Đôi khi chúng ta có thể cần tạo các quy trình mới để chạy các nhiệm vụ bổ sung đồng thời. Python cung cấp các quy trình cấp hệ thống thực thông qua lớp quy trình trong mô-đun đa xử lý.Process class in the multiprocessing module. Hệ điều hành cơ bản kiểm soát các quy trình mới được tạo ra. Trên một số hệ thống, điều đó có thể yêu cầu sinh sản một quy trình mới và trên các hệ thống khác, nó có thể yêu cầu quá trình này được đưa ra. Phương pháp cụ thể hoạt động được sử dụng để tạo các quy trình mới trong Python không phải là điều chúng ta cần phải lo lắng vì nó được quản lý bởi trình thông dịch Python đã cài đặt của bạn. Một tác vụ có thể được chạy trong một quy trình mới bằng cách tạo một thể hiện của lớp quy trình và chỉ định chức năng để chạy trong quy trình mới thông qua đối số Target Target.Process class and specifying the function to run in the new process via the “target” argument.
Khi quá trình được tạo, nó phải được bắt đầu bằng cách gọi phương thức start ().start() method.
Khi quá trình được tạo, nó phải được bắt đầu bằng cách gọi phương thức start ().
Khi quá trình được tạo, nó phải được bắt đầu bằng cách gọi phương thức start ().
# Đợi nhiệm vụ hoàn thànhProcess to run an ad hoc task function is listed below.
# điểm nhập cho chương trình # Làm vài thứ... Kết hợp điều này lại với nhau, ví dụ hoàn chỉnh về việc tạo một quy trình để chạy chức năng tác vụ ad hoc được liệt kê dưới đây. # SuperfastPython.com # Ví dụ về việc chạy một chức năng trong một quy trình mớiTừ quá trình nhập bộ xử lý đa xử lý # một nhiệm vụ để thực hiện trong một quy trình khác
& nbsp; & nbsp; & nbsp; & nbsp;# xác định một tác vụ để chạy trong một quy trình mới & nbsp; & nbsp; & nbsp; & nbsp;# Bắt đầu nhiệm vụ trong một quy trình mớimultiprocessing.Pool class. & nbsp; & nbsp; & nbsp; & nbsp;# chờ hoàn thành nhiệm vụĐiều này rất hữu ích để chạy các tác vụ ad hoc một lần trong một quy trình riêng biệt, mặc dù nó trở nên cồng kềnh khi bạn có nhiều nhiệm vụ để chạy.multiprocessing.pool.Pool class provides a process pool in Python. Mỗi quy trình được tạo ra đòi hỏi phải áp dụng các tài nguyên (ví dụ: một phiên bản của trình thông dịch Python và bộ nhớ cho không gian ngăn xếp chính của quy trình. Chi phí tính toán để thiết lập các quy trình có thể trở nên đắt đỏ nếu chúng ta đang tạo và phá hủy nhiều quy trình nhiều lần cho các nhiệm vụ ad hoc.multiprocessing.pool.Pool class can also be accessed by the alias multiprocessing.Pool. They can be used interchangeably. Thay vào đó, chúng tôi muốn giữ các quy trình công nhân xung quanh để tái sử dụng nếu chúng tôi mong đợi chạy nhiều nhiệm vụ ad hoc trong suốt chương trình của chúng tôi.
Nhóm quy trình là một mẫu lập trình để tự động quản lý một nhóm các quy trình công nhân. Nhóm chịu trách nhiệm cho một số lượng cố định các quy trình.
Khi quá trình được tạo, nó phải được bắt đầu bằng cách gọi phương thức start ().apply() and map(). Nhóm chịu trách nhiệm cho một số lượng cố định các quy trình.
Khi quá trình được tạo, nó phải được bắt đầu bằng cách gọi phương thức start (). Ví dụ:
Bây giờ chúng ta có một ý tưởng cấp cao về nhóm Python Process, hãy để Lôi nhìn vào vòng đời của lớp đa xử lý.pool.pool.multiprocessing.pool.Pool class. Vòng đời của đa bộ xử lý.poolĐa xử lý.pool cung cấp một nhóm các quy trình công nhân chung.multiprocessing.Pool provides a pool of generic worker processes. Nó được thiết kế để dễ dàng và đơn giản để sử dụng. Có bốn bước chính trong vòng đời của việc sử dụng lớp đa xử lý.pool, chúng là: Tạo, gửi, chờ đợi và tắt máy.multiprocessing.Pool class, they are: create, submit, wait, and shutdown.
Hình dưới đây giúp hình dung vòng đời của lớp đa xử lý.pool.multiprocessing.Pool class. Multiprocessing-Pool-Life-CycleHãy cùng xem xét kỹ hơn về từng bước vòng đời. Bước 1. Tạo nhóm quy trìnhĐầu tiên, một phiên bản đa xử lý.pool phải được tạo.multiprocessing.Pool instance must be created. Khi một thể hiện của một đa xử lý.pool được tạo, nó có thể được cấu hình.multiprocessing.Pool is created it may be configured. Nhóm quy trình có thể được cấu hình bằng cách chỉ định các đối số cho hàm tạo lớp đa xử lý.pool.multiprocessing.Pool class constructor. Các đối số cho hàm tạo như sau:
Có lẽ đối số quan trọng nhất là các quy trình của người Viking chỉ định số lượng quy trình con công nhân trong nhóm quy trình.processes” that specifies the number of worker child processes in the process pool. Theo mặc định, Trình xây dựng lớp Multiprocessing.Pool không lấy bất kỳ đối số nào.multiprocessing.Pool class constructor does not take any arguments. Ví dụ:
Điều này sẽ tạo ra một nhóm quy trình sẽ sử dụng một số quy trình công nhân phù hợp với số lượng lõi CPU logic trong hệ thống của bạn. Chúng tôi sẽ tìm hiểu thêm về cách định cấu hình nhóm trong các phần sau. Nếu bạn có thể chờ đợi, bạn có thể tìm hiểu thêm về cách định cấu hình nhóm quy trình trong hướng dẫn:
Tiếp theo, hãy để Lôi nhìn vào cách chúng ta có thể phát hành các nhiệm vụ cho nhóm quy trình. Bước 2. Gửi nhiệm vụ đến nhóm quy trìnhKhi đa xử lý.pool đã được tạo, bạn có thể gửi các tác vụ thực thi.multiprocessing.Pool has been created, you can submit tasks execution. Như đã thảo luận, có hai cách tiếp cận chính để gửi các nhiệm vụ đến nhóm quy trình, chúng là:
Hãy cùng nhau xem xét kỹ hơn từng cách tiếp cận. Bước 2A. Phát hành nhiệm vụ đồng bộViệc phát hành các nhiệm vụ đồng bộ có nghĩa là người gọi sẽ chặn cho đến khi nhiệm vụ hoặc nhiệm vụ ban hành đã hoàn thành. Chặn các cuộc gọi đến nhóm quy trình bao gồm Ứng dụng (), map () và starmap ().apply(), map(), and starmap(). Chúng tôi có thể phát hành các tác vụ một lần cho nhóm quy trình bằng hàm application ().apply() function. Hàm application () lấy tên của hàm để thực hiện theo quy trình công nhân. Cuộc gọi sẽ chặn cho đến khi chức năng được thực thi bởi một quy trình công nhân, sau thời gian đó nó sẽ quay lại.apply() function takes the name of the function to execute by a worker process. The call will block until the function is executed by a worker process, after which time it will return. Ví dụ:
Nhóm quy trình cung cấp một phiên bản song song của hàm Bản đồ tích hợp () để phát hành các tác vụ.map() function for issuing tasks. Ví dụ:
Hàm starmap () giống như phiên bản song song của hàm map (), ngoại trừ việc nó cho phép mỗi cuộc gọi hàm thực hiện nhiều đối số. Cụ thể, nó có một sự khác biệt trong đó mỗi mục là một đối số có thể lặp lại cho hàm đích.starmap() function is the same as the parallel version of the map() function, except that it allows each function call to take multiple arguments. Specifically, it takes an iterable where each item is an iterable of arguments for the target function. Ví dụ:
Hàm starmap () giống như phiên bản song song của hàm map (), ngoại trừ việc nó cho phép mỗi cuộc gọi hàm thực hiện nhiều đối số. Cụ thể, nó có một sự khác biệt trong đó mỗi mục là một đối số có thể lặp lại cho hàm đích. Forresult Instarmap (Nhiệm vụ, Mục):Chúng tôi sẽ xem xét kỹ hơn về cách phát hành các nhiệm vụ trong các phần sau. Bước 2b. Phát hành nhiệm vụ không đồng bộ Phát hành các nhiệm vụ không đồng bộ vào nhóm quy trình có nghĩa là người gọi sẽ không chặn, cho phép người gọi tiếp tục với các công việc khác trong khi các tác vụ đang thực hiện.apply_async(), map_async(), and starmap_async(). IMAP () và imap_unordered () rất thú vị. Họ trở lại ngay lập tức, vì vậy họ là các cuộc gọi không chặn kỹ thuật. Các điều có thể được trả lại sẽ mang lại các giá trị trả về khi các tác vụ được hoàn thành. Điều này có nghĩa là đi qua những điều khác nhau sẽ chặn.imap() and imap_unordered() are interesting. They return immediately, so they are technically non-blocking calls. The iterable that is returned will yield return values as tasks are completed. This means traversing the iterable will block. Application_async (), map_async () và starmap_async () là các phiên bản không đồng bộ của các hàm application (), map () và starmap () được mô tả ở trên.apply_async(), map_async(), and starmap_async() functions are asynchronous versions of the apply(), map(), and starmap() functions described above. Tất cả đều trả về một đối tượng không đồng bộ ngay lập tức cung cấp một tay cầm về nhiệm vụ hoặc nhiệm vụ đã phát hành.AsyncResult object immediately that provides a handle on the issued task or tasks. Ví dụ:
Hàm IMAP () lấy tên của hàm đích và có thể lặp lại như hàm map ().imap() function takes the name of a target function and an iterable like the map() function. Sự khác biệt là hàm imap () lười biếng hơn theo hai cách:
Ví dụ:
IMAP () đưa ra nhiều tác vụ cho từng nhóm một, thay vì tất cả cùng một lúc như Map ().imap_unordered() is the same as imap(), except that the returned iterable will yield return values in the order that tasks are completed (e.g. out of order). Ví dụ:
IMAP () đưa ra nhiều tác vụ cho từng nhóm một, thay vì tất cả cùng một lúc như Map ().
# lặp lại kết quả khi các nhiệm vụ được hoàn thành theo thứ tự Forresult Inimap (Nhiệm vụ, Mục):& nbsp; & nbsp; & nbsp; & nbsp;# ...AsyncResult object is returned when issuing tasks to multiprocessing.Pool the process pool asynchronously. IMAP_Unordered () giống như imap (), ngoại trừ việc có thể trả về sẽ mang lại các giá trị trả về theo thứ tự các tác vụ được hoàn thành (ví dụ: không theo thứ tự).
Nhóm đa xử lý áp dụng () vs map () vs imap () vs starmap ()AsyncResult provides a handle on one or more issued tasks. Bây giờ chúng ta đã biết cách phát hành các nhiệm vụ cho nhóm quy trình, hãy để xem xét kỹ hơn việc chờ đợi các nhiệm vụ hoàn thành hoặc nhận kết quả. Bước 3. Chờ các nhiệm vụ hoàn thành (tùy chọn)AsyncResult, such as if issued tasks do not return values and we are not concerned with when the tasks complete or whether they are completed successfully. Một đối tượng không đồng bộ được trả về khi ban hành các tác vụ để đa xử lý. Pool nhóm quy trình không đồng bộ. Điều này có thể đạt được thông qua bất kỳ phương pháp nào sau đây trên nhóm quy trình:AsyncResult to wait, they are:
Pool.starmap_async () để phát hành nhiều tác vụ có nhiều đối số. A Asyncresult cung cấp một tay cầm trên một hoặc nhiều nhiệm vụ được cấp.Nó cho phép người gọi kiểm tra trạng thái của các nhiệm vụ đã phát hành, chờ hoàn thành các nhiệm vụ và để có được kết quả sau khi hoàn thành các nhiệm vụ.AsyncResult.wait() function. Chúng tôi không cần sử dụng Asyncresult đã trả lại, chẳng hạn như nếu các nhiệm vụ được phát hành không trả lại giá trị và chúng tôi không quan tâm đến khi các nhiệm vụ hoàn thành hoặc liệu chúng có được hoàn thành thành công hay không. Ví dụ:
Tuy nhiên, có hai cách chính mà chúng ta có thể sử dụng không đồng bộ để chờ đợi, chúng là:wait() function will return immediately. Chờ các nhiệm vụ ban hành để hoàn thành.timeout” argument can be specified to set a limit in seconds for how long the caller is willing to wait. Chờ một kết quả từ các nhiệm vụ đã ban hành.wait() function will return. Hãy cùng nhau xem xét kỹ hơn từng cách tiếp cận.wait() function does not give an indication that it returned because tasks completed or because the timeout elapsed. Therefore, we can check if the tasks completed via the ready() function. Ví dụ:
Nếu các tác vụ đã hoàn thành, thì hàm Wait () sẽ quay lại ngay lập tức.Một đối số thời gian chờ của người Viking có thể được chỉ định để đặt giới hạn tính bằng giây trong thời gian người gọi sẵn sàng chờ đợi.AsyncResult.get() function. Nếu thời gian chờ hết hạn trước khi hoàn thành các tác vụ, hàm chờ () sẽ trở lại.
Ví dụ:
& nbsp; & nbsp; & nbsp; & nbsp; in ('chưa hoàn thành'))get() will block until the tasks are finished. 3B. Chờ các đối tượng không đồng bộ cho kết quả Chúng ta có thể nhận được kết quả của một tác vụ được phát hành bằng cách gọi hàm asyncresult.get (). Một đối số thời gian chờ của người Viking có thể được chỉ định. Nếu các tác vụ vẫn đang chạy và không hoàn thành trong số giây được chỉ định, thì một bộ xử lý.timeout” argument can be specified. If the tasks are still running and do not complete within the specified number of seconds, a multiprocessing.TimeoutError is raised. Bạn có thể tìm hiểu thêm về đối tượng Asyncresult trong hướng dẫn:
Tiếp theo, hãy để Lôi nhìn vào cách chúng ta có thể tắt nhóm quy trình sau khi chúng ta kết thúc với nó. Bước 4. Tắt máy quy trìnhĐa xử lý.pool có thể được đóng lại khi chúng tôi không có nhiệm vụ nào nữa để phát hành.multiprocessing.Pool can be closed once we have no further tasks to issue. Có hai cách để tắt nhóm quy trình. Họ đang:
Hàm đóng () sẽ quay lại ngay lập tức và nhóm sẽ không thực hiện bất kỳ nhiệm vụ nào nữa.close() function will return immediately and the pool will not take any further tasks. Ví dụ:
Ngoài ra, chúng tôi có thể muốn chấm dứt mạnh mẽ tất cả các quy trình công nhân trẻ em, bất kể họ có thực hiện các nhiệm vụ hay không. Điều này có thể đạt được thông qua hàm chấm dứt ().terminate() function. Ví dụ:
Ngoài ra, chúng tôi có thể muốn chấm dứt mạnh mẽ tất cả các quy trình công nhân trẻ em, bất kể họ có thực hiện các nhiệm vụ hay không. Điều này có thể đạt được thông qua hàm chấm dứt ().join() function on the pool. Ví dụ:
Ngoài ra, chúng tôi có thể muốn chấm dứt mạnh mẽ tất cả các quy trình công nhân trẻ em, bất kể họ có thực hiện các nhiệm vụ hay không.multiprocessing.Pool in the tutorial:
# Đóng mạnh tất cả các quy trình công nhân Chúng tôi có thể muốn sau đó chờ tất cả các nhiệm vụ trong hồ bơi kết thúc.Điều này có thể đạt được bằng cách gọi hàm tham gia () trên nhóm. # Đợi tất cả các nhiệm vụ đã cấp để hoàn thành Bạn có thể tìm hiểu thêm về việc tắt đa xử lý.pool trong hướng dẫn: Tắt máy nhân đa xử lý trong Python Ví dụ:
Điều này có thể đạt được bằng cách gọi hàm tham gia () trên nhóm. # Đợi tất cả các nhiệm vụ đã cấp để hoàn thànhmultiprocessing.Pool class, we can see that the __exit__() method calls the terminate() method on the process pool when exiting the context manager block. Bạn có thể tìm hiểu thêm về việc tắt đa xử lý.pool trong hướng dẫn: Tắt máy nhân đa xử lý trong Pythonmultiprocessing.Pool in the tutorial:
Bước 4A. Trình quản lý bối cảnh nhóm đa xử lý Trình quản lý bối cảnh là một giao diện trên các đối tượng Python để xác định bối cảnh chạy mới.Python cung cấp giao diện Trình quản lý bối cảnh trên nhóm quy trình.multiprocessing.Pool. Điều này đạt được một kết quả tương tự như sử dụng mẫu thử-ngoại trừ cuối cùng, với ít mã hơn. Cụ thể, nó giống như một mẫu thử cuối cùng, trong đó mọi xử lý ngoại lệ phải được thêm vào và xảy ra trong chính khối mã. # Tạo và định cấu hình nhóm quy trình với đa xử lý.pool () aspool: & nbsp; & nbsp; & nbsp; & nbsp;# phát hành các nhiệm vụ cho nhóm & nbsp; & nbsp; & nbsp; & nbsp;# ...# tự động đóng nhóm Có một sự khác biệt quan trọng với khối cố gắng. Nếu chúng ta xem mã nguồn cho lớp đa xử lý.pool, chúng ta có thể thấy rằng phương thức __exit __ () gọi phương thức interpinate () trên nhóm quy trình khi thoát khỏi khối trình quản lý ngữ cảnh.
Điều này có nghĩa là nhóm được đóng mạnh một khi khối trình quản lý bối cảnh bị thoát ra. Nó đảm bảo rằng các tài nguyên của nhóm quy trình được phát hành trước khi tiếp tục, nhưng không đảm bảo rằng các nhiệm vụ đã được phát hành được hoàn thành trước./usr/share/dict/words‘ and contains 235,886 words calculated using the command:
Trình quản lý bối cảnh nhóm đa xử lý Bị bối rối bởi API Lớp Pool? Tải xuống bảng cheat pdf miễn phí của tôi Ví dụ về nhóm đa xử lý
Hãy xem xét một tình huống mà chúng tôi có thể muốn kiểm tra xem một từ có được biết đến chương trình hay không, ví dụ: cho dù đó là trong một từ điển của các từ đã biết.1m_words.txt“. Nếu từ được biết, đó là tốt, nhưng nếu không, chúng tôi có thể muốn hành động cho người dùng, có lẽ nhấn mạnh nó trong đọc như kiểm tra chính tả tự động.
Đầu tiên, chúng ta cần tải danh sách các từ vào bộ nhớ. Điều này có thể đạt được bằng cách đầu tiên mở tệp, sau đó gọi hàm readlines () sẽ tự động đọc các dòng văn bản ASCII vào một danh sách.readlines() function that will automatically read ASCII lines of text into a list. Hàm load_words () bên dưới sẽ có một đường dẫn đến tệp văn bản và trả về một danh sách các từ được tải từ tệp.load_words() function below takes a path to the text file and returns a list of words loaded from the file.
Tiếp theo, chúng ta cần băm mỗi từ. Chúng tôi sẽ cố tình chọn hàm băm chậm trong ví dụ này, cụ thể là thuật toán SHA512. Điều này có sẵn trong Python thông qua hàm Hashlib.Sha512 ().hashlib.sha512() function. Bạn có thể tìm hiểu thêm về mô -đun Hashlib tại đây:
Đầu tiên, chúng ta có thể tạo một thể hiện của đối tượng băm bằng cách gọi hàm sha512 ().sha512() function.
Điều này có thể đạt được bằng cách đầu tiên mở tệp, sau đó gọi hàm readlines () sẽ tự động đọc các dòng văn bản ASCII vào một danh sách.
Hàm load_words () bên dưới sẽ có một đường dẫn đến tệp văn bản và trả về một danh sách các từ được tải từ tệp.hashlib.hexdigest() function.
Điều này có thể đạt được bằng cách đầu tiên mở tệp, sau đó gọi hàm readlines () sẽ tự động đọc các dòng văn bản ASCII vào một danh sách.hash_word() function below takes a word and returns a hex hash code of the word.
Tiếp theo, chúng ta cần băm mỗi từ. Chúng tôi sẽ cố tình chọn hàm băm chậm trong ví dụ này, cụ thể là thuật toán SHA512.load_words() then creating a set of hashes of known words by calling our hash_word() for each loaded word. Điều này có sẵn trong Python thông qua hàm Hashlib.Sha512 ().main() function below implements this.
# băm từ
# băm từ Cuối cùng, chúng ta có thể nhận được một biểu diễn chuỗi hex của băm cho từ bằng cách gọi hàm hashlib.hexdigest (). # Nhận Hex Hash of the Word Kết hợp điều này lại với nhau, hàm Hash_word () bên dưới lấy một từ và trả về mã băm hex của từ. Ví dụ mất bao lâu để chạy trên hệ thống của bạn? Hãy cho tôi biết trong các ý kiến dưới đây.
Tiếp theo, chúng tôi có thể cập nhật chương trình để băm các từ song song. Hash một từ điển của các từ đồng thời với bản đồ ()Các từ băm tương đối chậm, nhưng ngay cả như vậy, băm gần một triệu từ mất dưới hai giây. Tuy nhiên, chúng ta có thể tăng tốc quá trình bằng cách sử dụng tất cả các CPU trong hệ thống và băm đồng thời các từ. Điều này có thể đạt được bằng cách sử dụng đa xử lý.pool.multiprocessing.Pool. Đầu tiên, chúng tôi có thể tạo nhóm quy trình và chỉ định số lượng quy trình đồng thời để chạy. Tôi khuyên bạn nên định cấu hình nhóm để phù hợp với số lượng lõi CPU vật lý trong hệ thống của bạn. Tôi có bốn lõi, vì vậy ví dụ sẽ sử dụng bốn lõi, nhưng cập nhật nó cho số lượng lõi bạn có sẵn.
Tiếp theo, chúng ta cần gửi các nhiệm vụ cho nhóm quy trình, nghĩa là băm của mỗi từ. Vì nhiệm vụ chỉ đơn giản là áp dụng một hàm cho mỗi mục trong danh sách, chúng ta có thể sử dụng hàm bản đồ () trực tiếp.map() function directly. Ví dụ:
với Pool (4) Aspool: & nbsp; & nbsp; & nbsp; & nbsp;# ...main() function to hash words concurrently is listed below.
& nbsp; & nbsp; & nbsp; & nbsp;# tải một tệp từ
& nbsp; & nbsp; & nbsp; & nbsp;# tải một tệp từhash_word() function to each word in the loaded list as before, except this time the functions are executed in parallel using the process pool. & nbsp; & nbsp; & nbsp; & nbsp; print (f'loaded {len (từ)} từ từ {path} ') & nbsp; & nbsp; & nbsp; & nbsp;# tạo nhóm quy trình
& nbsp; & nbsp; & nbsp; & nbsp; với pool (4) aspool: & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; print (f'done, với {len (đã biết_ từ)} băm Tying này lại với nhau, ví dụ hoàn chỉnh được liệt kê dưới đây. # SuperfastPython.com# Ví dụ về việc băm một danh sách từ song song với một nhóm quy trìnhmultiprocessing.pool.Pool class constructor. từ trần nhập khẩu toán học
Theo mặc định, Tr trong trình xây dựng lớp Multiprocessing.Pool.Pool không lấy bất kỳ đối số nào.multiprocessing.pool.Pool class constructor does not take any arguments. Ví dụ:
Điều này sẽ tạo ra một nhóm quy trình sẽ sử dụng một số quy trình công nhân phù hợp với số lượng lõi CPU logic trong hệ thống của bạn. Nó sẽ không gọi một chức năng khởi tạo các quy trình của công nhân khi chúng được tạo. Mỗi quy trình của công nhân sẽ có thể thực hiện một số lượng nhiệm vụ không giới hạn trong nhóm. Cuối cùng, bối cảnh đa xử lý mặc định sẽ được sử dụng, cùng với phương thức bắt đầu hiện được cấu hình hoặc mặc định cho hệ thống. Bây giờ chúng ta đã biết cấu hình mà nhóm quy trình thực hiện, hãy để xem xét cách chúng ta có thể định cấu hình từng khía cạnh của nhóm quy trình. Cách định cấu hình số lượng quy trình công nhânChúng ta có thể định cấu hình số lượng các quy trình của công nhân trong đa xử lý.pool.pool bằng cách đặt đối số của các quy trình trên mạng trong hàm tạo.multiprocessing.pool.Pool by setting the “processes” argument in the constructor.
Chúng tôi có thể đặt đối số quy trình của các quy trình trên mạng để chỉ định số lượng quy trình con để tạo và sử dụng làm công nhân trong nhóm quy trình.processes” argument to specify the number of child processes to create and use as workers in the process pool. Ví dụ:
Điều này sẽ tạo ra một nhóm quy trình sẽ sử dụng một số quy trình công nhân phù hợp với số lượng lõi CPU logic trong hệ thống của bạn.processes” argument is the first argument in the constructor and does not need to be specified by name to be set, for example:
Điều này sẽ tạo ra một nhóm quy trình sẽ sử dụng một số quy trình công nhân phù hợp với số lượng lõi CPU logic trong hệ thống của bạn. Ví dụ:
Mỗi quy trình của công nhân sẽ có thể thực hiện một số lượng nhiệm vụ không giới hạn trong nhóm.
Bây giờ chúng ta đã biết cấu hình mà nhóm quy trình thực hiện, hãy để xem xét cách chúng ta có thể định cấu hình từng khía cạnh của nhóm quy trình. Cách định cấu hình số lượng quy trình công nhânChúng ta có thể định cấu hình số lượng các quy trình của công nhân trong đa xử lý.pool.pool bằng cách đặt đối số của các quy trình trên mạng trong hàm tạo. Các quy trình là số lượng quy trình công nhân để sử dụng. Nếu các quy trình không có thì số được trả về bởi OS.cpu_count () được sử dụng.initializer” argument when configuring the process pool via the class constructor. -Đa xử lý-song song dựa trên quy trìnhinitializer” argument can be set to the name of a function that will be called to initialize the worker processes.
Ví dụ:
Điều này sẽ tạo ra một nhóm quy trình sẽ sử dụng một số quy trình công nhân phù hợp với số lượng lõi CPU logic trong hệ thống của bạn.initargs” argument, which takes an ordered list or tuple of arguments for the custom initialization function. Ví dụ:
Điều này sẽ tạo ra một nhóm quy trình sẽ sử dụng một số quy trình công nhân phù hợp với số lượng lõi CPU logic trong hệ thống của bạn.
Mỗi quy trình của công nhân sẽ có thể thực hiện một số lượng nhiệm vụ không giới hạn trong nhóm. Cuối cùng, bối cảnh đa xử lý mặc định sẽ được sử dụng, cùng với phương thức bắt đầu hiện được cấu hình hoặc mặc định cho hệ thống.Bây giờ chúng ta đã biết cấu hình mà nhóm quy trình thực hiện, hãy để xem xét cách chúng ta có thể định cấu hình từng khía cạnh của nhóm quy trình.maxtasksperchild” argument in the multiprocessing.pool.Pool class constructor when configuring a new process pool. Ví dụ:
Điều này sẽ tạo ra một nhóm quy trình sẽ sử dụng một số quy trình công nhân phù hợp với số lượng lõi CPU logic trong hệ thống của bạn.
Theo mặc định, đối số MaxTasksperChild được đặt thành không có, điều đó có nghĩa là mỗi quy trình nhân viên con sẽ chạy trong thời gian sử dụng của nhóm quy trình.
Bạn có thể tìm hiểu thêm về việc định cấu hình các tác vụ tối đa cho mỗi quy trình công nhân trong hướng dẫn:
Tiếp theo, hãy để Lôi nhìn vào cách chúng ta có thể định cấu hình bối cảnh đa xử lý cho nhóm. Cách định cấu hình ngữ cảnhChúng ta có thể đặt bối cảnh cho nhóm quy trình thông qua đối số ngữ cảnh của nhóm thành một trình xây dựng lớp đa xử lý.pool.pool.context” argument to the multiprocessing.pool.Pool class constructor.
Bối cảnh của người Viking là một thể hiện của bối cảnh đa xử lý được cấu hình bằng phương thức bắt đầu, được tạo thông qua hàm đa biến.get_context ().context” is an instance of a multiprocessing context configured with a start method, created via the multiprocessing.get_context() function. Theo mặc định, bối cảnh của Nhật Bản là không có, sử dụng bối cảnh mặc định hiện tại và phương thức bắt đầu được cấu hình cho ứng dụng.context” is None, which uses the current default context and start method configured for the application. Phương pháp bắt đầu là kỹ thuật được sử dụng để bắt đầu các quá trình trẻ em trong Python. Có ba phương pháp bắt đầu, chúng là:
Bối cảnh đa xử lý cung cấp một cách linh hoạt hơn để quản lý các phương thức bắt đầu quá trình trực tiếp trong một chương trình và có thể là một cách tiếp cận ưa thích để thay đổi các phương thức bắt đầu nói chung, đặc biệt là trong thư viện Python. Một bối cảnh mới có thể được tạo với một phương thức bắt đầu nhất định và được chuyển đến nhóm quy trình. Ví dụ:
Bạn có thể tìm hiểu thêm về việc định cấu hình ngữ cảnh cho nhóm quy trình trong hướng dẫn:
Nhiệm vụ phát hành nhóm đa xử lýTrong phần này, chúng ta sẽ xem xét kỹ hơn các cách khác nhau mà chúng ta có thể đưa ra các nhiệm vụ cho nhóm đa xử lý. Bể bơi cung cấp 8 cách để phát hành các nhiệm vụ cho người lao động trong nhóm quy trình. Họ đang:
Hãy để lần lượt xem xét kỹ hơn và ngắn gọn về từng cách tiếp cận. Cách sử dụng pool.apply ()Chúng tôi có thể phát hành các tác vụ một lần cho nhóm quy trình bằng hàm application ().apply() function. Hàm application () lấy tên của hàm để thực hiện theo quy trình công nhân. Cuộc gọi sẽ chặn cho đến khi chức năng được thực thi bởi một quy trình công nhân, sau thời gian đó nó sẽ quay lại.apply() function takes the name of the function to execute by a worker process. The call will block until the function is executed by a worker process, after which time it will return. Ví dụ:
# Tạo một nhóm quy trình với bối cảnh nhất địnhPool.apply() function is a parallel version of the now deprecated built-in apply() function. Bạn có thể tìm hiểu thêm về việc định cấu hình ngữ cảnh cho nhóm quy trình trong hướng dẫn:apply() method are as follows:
Bể bơi cung cấp 8 cách để phát hành các nhiệm vụ cho người lao động trong nhóm quy trình.apply() method in the tutorial:
Hãy để lần lượt xem xét kỹ hơn và ngắn gọn về từng cách tiếp cận.Cách sử dụng pool.apply ()apply_async() function. Chúng tôi có thể phát hành các tác vụ một lần cho nhóm quy trình bằng hàm application (). Hàm application () lấy tên của hàm để thực hiện theo quy trình công nhân. Cuộc gọi sẽ chặn cho đến khi chức năng được thực thi bởi một quy trình công nhân, sau thời gian đó nó sẽ quay lại.apply_async() function takes the name of the function to execute in a worker process and returns immediately with a AsyncResult object for the task. # Phát hành một nhiệm vụ cho nhóm quy trình Ví dụ:
# Tạo một nhóm quy trình với bối cảnh nhất định Ví dụ:
# Tạo một nhóm quy trình với bối cảnh nhất địnhapply_async() method are as follows:
Họ đang:apply_async() method in the tutorial:
Cách sử dụng pool.apply ()Chúng tôi có thể phát hành các tác vụ một lần cho nhóm quy trình bằng hàm application ().map() function for issuing tasks. Hàm application () lấy tên của hàm để thực hiện theo quy trình công nhân. Cuộc gọi sẽ chặn cho đến khi chức năng được thực thi bởi một quy trình công nhân, sau thời gian đó nó sẽ quay lại.map() function takes the name of a target function and an iterable. A task is created to call the target function for each item in the provided iterable. It returns an iterable over the return values from each call to the target function. Điều đó có thể đi qua đầu tiên và tất cả các nhiệm vụ được ban hành cùng một lúc. Một đoạn có thể được chỉ định để chia các tác vụ thành các nhóm có thể được gửi đến từng quy trình của công nhân để được thực thi theo đợt. Ví dụ:
Hàm pool.map () là phiên bản song song của hàm bản đồ tích hợp ().Pool.map() function is a parallel version of the built-in map() function. Tóm lại, các khả năng của phương thức Bản đồ () như sau:
Bạn có thể tìm hiểu thêm về phương thức Bản đồ () trong hướng dẫn:map() method in the tutorial:
Cách sử dụng pool.map_async ()Nhóm quy trình cung cấp một phiên bản không đồng bộ của hàm Bản đồ tích hợp () để phát hành các tác vụ gọi là MAP_ASYNC ().map() function for issuing tasks called map_async() function. Hàm map_async () có tên của hàm đích và có thể điều chỉnh được. Một tác vụ được tạo để gọi hàm đích cho từng mục trong ITable được cung cấp. Nó không chặn và trả lại ngay lập tức với một sự bất biến có thể được sử dụng để truy cập vào kết quả.map_async() function takes the name of a target function and an iterable. A task is created to call the target function for each item in the provided iterable. It does not block and returns immediately with an AsyncResult that may be used to access the results. Điều đó có thể đi qua đầu tiên và tất cả các nhiệm vụ được ban hành cùng một lúc. Một đoạn có thể được chỉ định để chia các tác vụ thành các nhóm có thể được gửi đến từng quy trình của công nhân để được thực thi theo đợt. Nó hỗ trợ chức năng gọi lại cho kết quả và chức năng gọi lại lỗi nếu lỗi được nêu ra. Ví dụ:
forresult inpool.map (nhiệm vụ, các mục): Ví dụ:
Hàm pool.map () là phiên bản song song của hàm bản đồ tích hợp ().map_async() method are as follows:
Nhóm đa xử lý.map () trong Pythonmap_async() method in the tutorial:
Nhóm quy trình cung cấp một phiên bản không đồng bộ của hàm Bản đồ tích hợp () để phát hành các tác vụ gọi là MAP_ASYNC ().Hàm map_async () có tên của hàm đích và có thể điều chỉnh được. Một tác vụ được tạo để gọi hàm đích cho từng mục trong ITable được cung cấp. Nó không chặn và trả lại ngay lập tức với một sự bất biến có thể được sử dụng để truy cập vào kết quả.imap() function. Điều đó có thể đi qua đầu tiên và tất cả các nhiệm vụ được ban hành cùng một lúc. Một đoạn có thể được chỉ định để chia các tác vụ thành các nhóm có thể được gửi đến từng quy trình của công nhân để được thực thi theo đợt. Nó hỗ trợ chức năng gọi lại cho kết quả và chức năng gọi lại lỗi nếu lỗi được nêu ra.imap() function takes the name of a target function and an iterable. A task is created to call the target function for each item in the provided iterable. # Phát hành các nhiệm vụ cho nhóm quy trình không đồng bộ Sau đó, trạng thái của các tác vụ có thể được kiểm tra và các giá trị trả về từ mỗi cuộc gọi đến hàm đích có thể được lặp lại.imap() function is lazy in that it traverses the provided iterable and issues tasks to the process pool one by one as space becomes available in the process pool. A chunksize can be specified to split the tasks into groups which may be sent to each worker process to be executed in batch. Ví dụ:
Hàm pool.map () là phiên bản song song của hàm bản đồ tích hợp ().Pool.imap() function is a parallel version of the now deprecated itertools.imap() function. Tóm lại, các khả năng của phương thức Bản đồ () như sau:imap() method are as follows:
Bạn có thể tìm hiểu thêm về phương thức Bản đồ () trong hướng dẫn:imap() method in the tutorial:
Cách sử dụng pool.map_async ()Nhóm quy trình cung cấp một phiên bản không đồng bộ của hàm Bản đồ tích hợp () để phát hành các tác vụ gọi là MAP_ASYNC ().imap_unordered() function. Hàm map_async () có tên của hàm đích và có thể điều chỉnh được. Một tác vụ được tạo để gọi hàm đích cho từng mục trong ITable được cung cấp. Nó không chặn và trả lại ngay lập tức với một sự bất biến có thể được sử dụng để truy cập vào kết quả.imap_unordered() function takes the name of a target function and an iterable. A task is created to call the target function for each item in the provided iterable. Điều đó có thể đi qua đầu tiên và tất cả các nhiệm vụ được ban hành cùng một lúc. Một đoạn có thể được chỉ định để chia các tác vụ thành các nhóm có thể được gửi đến từng quy trình của công nhân để được thực thi theo đợt. Nó hỗ trợ chức năng gọi lại cho kết quả và chức năng gọi lại lỗi nếu lỗi được nêu ra. # Phát hành các nhiệm vụ cho nhóm quy trình không đồng bộimap_unordered() function is lazy in that it traverses the provided iterable and issues tasks to the process pool one by one as space becomes available in the process pool. A chunksize can be specified to split the tasks into groups which may be sent to each worker process to be executed in batch. Ví dụ:
Tóm lại, các khả năng của phương thức imap_Unordered () như sau:imap_unordered() method are as follows:
Bạn có thể tìm hiểu thêm về phương thức imap_Unordered () trong hướng dẫn:imap_unordered() method in the tutorial:
Cách sử dụng pool.starmap ()Chúng tôi có thể phát hành nhiều tác vụ cho nhóm quy trình bằng hàm starmap ().starmap() function. Hàm starmap () lấy tên của hàm đích và có thể điều chỉnh được. Một tác vụ được tạo để gọi hàm đích cho từng mục trong ITable được cung cấp. Mỗi mục trong ITEBLE có thể là một điều đáng tin cậy, cho phép nhiều đối số được cung cấp cho chức năng đích.starmap() function takes the name of a target function and an iterable. A task is created to call the target function for each item in the provided iterable. Each item in the iterable may itself be an iterable, allowing multiple arguments to be provided to the target function. Nó trả về một sự lặp lại trên các giá trị trả về từ mỗi cuộc gọi đến hàm đích. Điều đó có thể đi qua đầu tiên và tất cả các nhiệm vụ được ban hành cùng một lúc. Một đoạn có thể được chỉ định để chia các tác vụ thành các nhóm có thể được gửi đến từng quy trình của công nhân để được thực thi theo đợt. Ví dụ:
Tóm lại, các khả năng của phương thức imap_Unordered () như sau:Pool.starmap() function is a parallel version of the itertools.starmap() function. Đưa ra nhiều nhiệm vụ cho nhóm quy trình, từng người một.starmap() method are as follows:
Bạn có thể tìm hiểu thêm về phương thức imap_Unordered () trong hướng dẫn:starmap() method in the tutorial:
Cách sử dụng pool.starmap ()Chúng tôi có thể phát hành nhiều tác vụ cho nhóm quy trình bằng hàm starmap ().starmap_async() function. Hàm starmap () lấy tên của hàm đích và có thể điều chỉnh được. Một tác vụ được tạo để gọi hàm đích cho từng mục trong ITable được cung cấp. Mỗi mục trong ITEBLE có thể là một điều đáng tin cậy, cho phép nhiều đối số được cung cấp cho chức năng đích.starmap_async() function takes the name of a target function and an iterable. A task is created to call the target function for each item in the provided iterable. Each item in the iterable may itself be an iterable, allowing multiple arguments to be provided to the target function. Nó trả về một sự lặp lại trên các giá trị trả về từ mỗi cuộc gọi đến hàm đích. Điều đó có thể đi qua đầu tiên và tất cả các nhiệm vụ được ban hành cùng một lúc. Một đoạn có thể được chỉ định để chia các tác vụ thành các nhóm có thể được gửi đến từng quy trình của công nhân để được thực thi theo đợt.AsyncResult that may be used to access the results. # lặp lại các giá trị trả về từ các tác vụ đã cấp Ví dụ:
Hàm pool.starmap () là phiên bản song song của hàm itertools.starmap (). Ví dụ:
Tóm lại, các khả năng của phương thức imap_Unordered () như sau:starmap_async() method are as follows:
Nhóm đa xử lý.imap_unordered () trong pythonstarmap_async() method in the tutorial:
Chúng tôi có thể phát hành nhiều tác vụ cho nhóm quy trình bằng hàm starmap ().Hàm starmap () lấy tên của hàm đích và có thể điều chỉnh được. Một tác vụ được tạo để gọi hàm đích cho từng mục trong ITable được cung cấp. Mỗi mục trong ITEBLE có thể là một điều đáng tin cậy, cho phép nhiều đối số được cung cấp cho chức năng đích. Nó trả về một sự lặp lại trên các giá trị trả về từ mỗi cuộc gọi đến hàm đích. Điều đó có thể đi qua đầu tiên và tất cả các nhiệm vụ được ban hành cùng một lúc. Một đoạn có thể được chỉ định để chia các tác vụ thành các nhóm có thể được gửi đến từng quy trình của công nhân để được thực thi theo đợt.
Khối cho đến khi tất cả các nhiệm vụ ban hành được hoàn thành. Bạn có thể tìm hiểu thêm về phương thức starmap () trong hướng dẫn: Nhóm đa xử lý.starmap () trong pythonCách sử dụng pool.starmap_async ()
Cách sử dụng Asyncresult chi tiếtMột đối tượng đa xử lý.pool.asyncresult được trả về khi phát hành các tác vụ để đa xử lý.pool.pool nhóm quy trình không đồng bộ.multiprocessing.pool.AsyncResult object is returned when issuing tasks to multiprocessing.pool.Pool the process pool asynchronously. Điều này có thể đạt được thông qua bất kỳ phương pháp nào sau đây trên nhóm quy trình:
Một đối tượng không đồng bộ cung cấp một tay cầm trên một hoặc nhiều tác vụ được cấp.AsyncResult object provides a handle on one or more issued tasks. Nó cho phép người gọi kiểm tra trạng thái của các nhiệm vụ đã phát hành, chờ hoàn thành các nhiệm vụ và để có được kết quả sau khi hoàn thành các nhiệm vụ. Làm thế nào để có được một đối tượng không liên quanLớp không đồng bộ là đơn giản để sử dụng.AsyncResult class is straightforward to use. Đầu tiên, bạn phải nhận được một đối tượng Asyncresult bằng cách phát hành một hoặc nhiều tác vụ cho nhóm quy trình bằng bất kỳ hàm application_async (), map_async () hoặc starmap_async ().AsyncResult object by issuing one or more tasks to the process pool using any of the apply_async(), map_async(), or starmap_async() functions. Ví dụ:
Khi bạn có một đối tượng Asyncresult, bạn có thể sử dụng nó để truy vấn trạng thái và nhận kết quả từ nhiệm vụ.AsyncResult object, you can use it to query the status and get results from the task. Làm thế nào để có được kết quảChúng ta có thể nhận được kết quả của một tác vụ được phát hành bằng cách gọi hàm asyncresult.get ().AsyncResult.get() function.
Điều này sẽ trả về kết quả của chức năng cụ thể được gọi để phát hành nhiệm vụ.
Ví dụ:
Khi bạn có một đối tượng Asyncresult, bạn có thể sử dụng nó để truy vấn trạng thái và nhận kết quả từ nhiệm vụ.get() will block until the tasks are finished. Làm thế nào để có được kết quảtimeout” argument can be specified. If the tasks are still running and do not complete within the specified number of seconds, a multiprocessing.TimeoutError is raised.
Ví dụ:
Chúng ta có thể nhận được kết quả của một tác vụ được phát hành bằng cách gọi hàm asyncresult.get (). Trả lại kết quả khi nó đến.
Ví dụ:
Chúng ta có thể nhận được kết quả của một tác vụ được phát hành bằng cách gọi hàm asyncresult.get ().Trả lại kết quả khi nó đến.AsyncResult.wait() function. -Đa xử lý-song song dựa trên quy trình Ví dụ:
Khi bạn có một đối tượng Asyncresult, bạn có thể sử dụng nó để truy vấn trạng thái và nhận kết quả từ nhiệm vụ.wait() function will return immediately. Làm thế nào để có được kết quảtimeout” argument can be specified to set a limit in seconds for how long the caller is willing to wait.
Ứng dụng_async (): Trả về giá trị trả về của hàm đích.wait() function will return. MAP_ASYNC (): Trả về một giá trị hoàn trả của hàm mục tiêu.wait() function does not give an indication that it returned because tasks completed or because the timeout elapsed. Therefore, we can check if the tasks completed via the ready() function. Ví dụ:
Trả lại kết quả khi nó đến.-Đa xử lý-song song dựa trên quy trìnhAsyncResult.ready() function.
Điều này sẽ trả về kết quả của chức năng cụ thể được gọi để phát hành nhiệm vụ.True if the tasks have completed, successfully or otherwise, or False if the tasks are still running. Ví dụ:
Chúng ta có thể nhận được kết quả của một tác vụ được phát hành bằng cách gọi hàm asyncresult.get ().Trả lại kết quả khi nó đến.AsyncResult.successful() function. Các nhiệm vụ được ban hành là thành công nếu không có nhiệm vụ nêu ra một ngoại lệ. Nếu ít nhất một nhiệm vụ được ban hành đã đưa ra một ngoại lệ, thì cuộc gọi không thành công và hàm thành công () sẽ trả về sai.successful() function will return False. Hàm này nên được gọi sau khi người ta biết rằng các nhiệm vụ đã hoàn thành, ví dụ: Sẵn sàng () trả về đúng.ready() returns True. Ví dụ:
Nếu các nhiệm vụ được phát hành vẫn đang chạy, một giá trị sẽ được nâng lên.ValueError is raised.
Ví dụ:
-Đa xử lý-song song dựa trên quy trìnhAsyncResult object in the tutorial:
& nbsp; & nbsp; & nbsp; & nbsp; in ('các nhiệm vụ vẫn đang chạy')) Bạn có thể tìm hiểu thêm về cách sử dụng đối tượng Asyncresult trong hướng dẫn:Đa bộ xử lý không đồng bộ trong Pythonmultiprocessing.Pool supports custom callback functions. Tiếp theo, chúng ta hãy xem cách sử dụng các chức năng gọi lại với các tác vụ không đồng bộ.
Các chức năng gọi lại được gọi trong hai tình huống: Với kết quả của một nhiệm vụ.Khi một lỗi được nêu ra trong một nhiệm vụ.
Ứng dụng_async (): Để ban hành một nhiệm vụ không đồng bộ.callback” argument. MAP_ASYNC (): Để phát hành nhiều nhiệm vụ với một đối số không đồng bộ. Starmap_async (): Để phát hành nhiều nhiệm vụ với nhiều đối số không đồng bộ.None will be passed as an argument to the callback function. Một cuộc gọi lại kết quả có thể được chỉ định thông qua đối số gọi lại trên mạng.
Ngoại trừ ValueError ASE:apply_async() is configured with a callback, then the callback function will be called with the return value of the task function that was executed.
& nbsp; & nbsp; & nbsp; & nbsp;# kiểm tra xem các tác vụ có thành công khôngmap_async() or starmap_async() are configured with a callback, then the callback function will be called with an iterable of return values from all tasks issued to the process pool.
& nbsp; & nbsp; & nbsp; & nbsp;# kiểm tra xem các tác vụ có thành công không Nếu các nhiệm vụ được phát hành vẫn đang chạy, một giá trị sẽ được nâng lên.
Ngoại trừ ValueError ASE:& nbsp; & nbsp; & nbsp; & nbsp; in ('các nhiệm vụ vẫn đang chạy'))
Ứng dụng_async (): Để ban hành một nhiệm vụ không đồng bộ.error_callback” argument. MAP_ASYNC (): Để phát hành nhiều nhiệm vụ với một đối số không đồng bộ. Starmap_async (): Để phát hành nhiều nhiệm vụ với nhiều đối số không đồng bộ. Một cuộc gọi lại kết quả có thể được chỉ định thông qua đối số gọi lại trên mạng.
Ví dụ: nếu application_async () được cấu hình với một cuộc gọi lại lỗi, thì hàm gọi lại sẽ được gọi với lỗi được nêu trong tác vụ.apply_async() is configured with an error callback, then the callback function will be called with the error raised in the task.
Lỗi gọi lại nên được sử dụng để thực hiện hành động nhanh với lỗi được đưa ra bởi một tác vụ trong nhóm quy trình. Họ không nên chặn hoặc thực hiện trong một thời gian dài vì họ sẽ chiếm các tài nguyên của nhóm quy trình trong khi chạy. Tiếp theo, hãy để Lôi nhìn vào các mẫu sử dụng phổ biến cho nhóm đa xử lý. Đa xử lý các mẫu sử dụng phổ biếnĐa xử lý.pool cung cấp rất nhiều tính linh hoạt để thực hiện các nhiệm vụ đồng thời trong Python.multiprocessing.Pool provides a lot of flexibility for executing concurrent tasks in Python. Tuy nhiên, có một số ít các mẫu sử dụng phổ biến sẽ phù hợp với hầu hết các kịch bản chương trình. Phần này liệt kê các mẫu sử dụng phổ biến với các ví dụ đã làm việc mà bạn có thể sao chép và dán vào dự án của riêng bạn và thích ứng khi cần thiết. Các mẫu chúng ta sẽ xem xét như sau:
Chúng tôi sẽ sử dụng một nhiệm vụ giả định trong mỗi ví dụ sẽ ngủ trong một khoảng thời gian ngẫu nhiên bằng dưới một giây. Bạn có thể dễ dàng thay thế nhiệm vụ ví dụ này bằng nhiệm vụ của riêng bạn trong mỗi mẫu. Hãy bắt đầu với mẫu sử dụng đầu tiên. Mẫu 1: Mẫu bản đồ () và lặp lại kết quảMẫu 2: Ứng dụng_async () và quên mẫu Mẫu 3: map_async () và quên mẫumap() function with the main difference that all function calls are issued to the process pool immediately and we cannot process results until all tasks are completed. Mẫu 4: imap_unordered () và sử dụng làm mẫu đã hoàn thànhmap() function with our target function and an iterable of arguments and process return values from each function call in a for loop.
Tiếp theo, hãy để Lôi nhìn vào các mẫu sử dụng phổ biến cho nhóm đa xử lý.map() function on the process pool in the tutorial:
Đa xử lý.pool cung cấp rất nhiều tính linh hoạt để thực hiện các nhiệm vụ đồng thời trong Python.map() function for the starmap() function. Tuy nhiên, có một số ít các mẫu sử dụng phổ biến sẽ phù hợp với hầu hết các kịch bản chương trình.starmap() function in the tutorial:
Các mẫu chúng ta sẽ xem xét như sau:
Bạn có thể tìm hiểu thêm về hàm starmap () trong hướng dẫn:map() function is called the task() function for each argument in the range 0 to 9. Nhóm đa xử lý.starmap () trong python
Mẫu 2: Ứng dụng_async () và quên mẫuMẫu 3: map_async () và quên mẫu Mẫu 4: imap_unordered () và sử dụng làm mẫu đã hoàn thành Mẫu 5: imap_unordered () và đợi mẫu đầu tiênapply_async() function with the name of the target function and any arguments the target function may take. Hàm application_async () sẽ trả về một đối tượng không đồng bộ có thể bị bỏ qua.apply_async() function will return an AsyncResult object that can be ignored. Ví dụ:
Bạn có thể tìm hiểu thêm về hàm application_async () trong hướng dẫn:apply_async() function in the tutorial:
Khi tất cả các nhiệm vụ ad hoc đã được ban hành, chúng tôi có thể muốn chờ các nhiệm vụ hoàn thành trước khi đóng nhóm quy trình. Điều này có thể đạt được bằng cách gọi hàm đóng () trên nhóm để ngăn nó nhận thêm bất kỳ nhiệm vụ nào nữa, sau đó tham gia nhóm để chờ hoàn thành các nhiệm vụ đã phát hành.close() function on the pool to prevent it from receiving any further tasks, then joining the pool to wait for the issued tasks to complete.
Nhóm đa xử lý.apply_async () trong python
Điều này có thể đạt được bằng cách gọi hàm đóng () trên nhóm để ngăn nó nhận thêm bất kỳ nhiệm vụ nào nữa, sau đó tham gia nhóm để chờ hoàn thành các nhiệm vụ đã phát hành.
& nbsp; & nbsp; & nbsp; & nbsp;# tạo nhóm quy trình & nbsp; & nbsp; & nbsp; & nbsp; với pool () aspool: & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;#
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;Chạy ví dụ bắn một nhiệm vụ vào nhóm quy trình và quên nó, cho phép nó hoàn thành trong nền. Nhiệm vụ được ban hành và quy trình chính là miễn phí để tiếp tục với các phần khác của chương trình. Trong ví dụ đơn giản này, không có gì khác để tiếp tục, vì vậy quy trình chính sau đó đóng nhóm và chờ tất cả các nhiệm vụ lửa và lửa ad hoc hoàn thành trước khi chấm dứt. > Nhiệm vụ có (1, 0.1278130542799114)map_async() function that takes the name of the target task and an iterable of arguments for each function call. Mẫu 3: map_async () và quên mẫuAsyncResult object that provides a handle on the issued tasks, that can be ignored in this case. Ví dụ:
Điều này rất hữu ích cho việc áp dụng cùng một chức năng cho từng mục trong một mục có thể lặp lại và sau đó không quan tâm đến kết quả hoặc giá trị trả về.map_async() function in the tutorial:
Điều này có thể đạt được với hàm map_async () có tên của tác vụ mục tiêu và có thể lặp lại các đối số cho mỗi cuộc gọi chức năng.
Điều này có thể đạt được bằng cách gọi hàm đóng () trên nhóm để ngăn nó nhận thêm bất kỳ nhiệm vụ nào nữa, sau đó tham gia nhóm để chờ hoàn thành các nhiệm vụ đã phát hành.
Chạy ví dụ phát hành mười nhiệm vụ cho nhóm quy trình. Cuộc gọi trả về ngay lập tức và các nhiệm vụ được thực hiện không đồng bộ. Điều này cho phép quá trình chính tiếp tục với các phần khác của chương trình. Không có gì khác để làm trong ví dụ đơn giản này, vì vậy nhóm quy trình sau đó được đóng lại và các khối quy trình chính, chờ hoàn thành các nhiệm vụ đã phát hành.
Mẫu 4: imap_unordered () và sử dụng làm mẫu đã hoàn thànhMô hình này là về việc phát hành các nhiệm vụ cho nhóm và sử dụng kết quả cho các nhiệm vụ khi chúng có sẵn. Điều này có nghĩa là kết quả được nhận ra khỏi trật tự, nếu các nhiệm vụ mất một lượng thời gian thay đổi, thay vì theo thứ tự các nhiệm vụ được cấp cho nhóm quy trình. Điều này có thể đạt được với hàm imap_unordered (). Nó có một chức năng và có thể lặp lại của các đối số, giống như hàm map ().imap_unordered() function. It takes a function and an iterable of arguments, just like the map() function. Nó trả về một số lượng có thể mang lại các giá trị trả về từ hàm đích khi các tác vụ được hoàn thành. Chúng ta có thể gọi hàm imap_unordered () và lặp lại các giá trị trả về trực tiếp trong vòng lặp.imap_unordered() function and iterate the return values directly in a for-loop. Ví dụ:
Bạn có thể tìm hiểu thêm về hàm imap_unordered () trong hướng dẫn:imap_unordered() function in the tutorial:
Tying này lại với nhau, ví dụ hoàn chỉnh được liệt kê dưới đây.
Chạy ví dụ phát hành tất cả các nhiệm vụ cho nhóm, sau đó nhận và xử lý kết quả theo thứ tự các tác vụ được hoàn thành, chứ không phải thứ tự các tác vụ được cấp cho nhóm, ví dụ: không đặt hàng.
Mẫu 5: imap_unordered () và đợi mẫu đầu tiênMô hình này liên quan đến việc phát hành nhiều nhiệm vụ cho nhóm quy trình không đồng bộ, sau đó chờ kết quả đầu tiên hoặc nhiệm vụ đầu tiên hoàn thành. Đó là một mô hình hữu ích khi có thể có nhiều cách để có được kết quả nhưng chỉ cần một hoặc kết quả đầu tiên là bắt buộc, sau đó, tất cả các nhiệm vụ khác trở nên không liên quan. Điều này có thể đạt được bằng hàm imap_unordered (), giống như hàm map (), lấy tên của hàm đích và có thể lặp lại các đối số.imap_unordered() function that, like the map() function, takes the name of a target function and an iterable of arguments. Nó trả về một số lượng có thể mang lại các giá trị trả về theo thứ tự hoàn thành nhiệm vụ. Điều này có thể đi qua một lần một lần theo cách thủ công thông qua hàm tích hợp tiếp theo () sẽ chỉ quay lại một khi nhiệm vụ đầu tiên hoàn thành lợi nhuận.next() built-in function which will return only once the first task to finish returns. Ví dụ:
& nbsp; & nbsp; & nbsp; & nbsp; print (f '> got {result}')) Tying này lại với nhau, ví dụ hoàn chỉnh được liệt kê dưới đây.
Chạy ví dụ đầu tiên phát hành tất cả các nhiệm vụ không đồng bộ. Kết quả từ nhiệm vụ đầu tiên để hoàn thành sau đó được yêu cầu, chặn cho đến khi có kết quả. Một nhiệm vụ hoàn thành, trả về một giá trị, sau đó được xử lý, sau đó nhóm quy trình và tất cả các nhiệm vụ còn lại được chấm dứt tự động.
Khi nào sử dụng nhóm đa xử lýĐa xử lý.pool mạnh mẽ và linh hoạt, mặc dù không phù hợp với tất cả các tình huống mà bạn cần chạy một tác vụ nền hoặc áp dụng một hàm cho mỗi mục trong một song song.multiprocessing.Pool is powerful and flexible, although is not suited for all situations where you need to run a background task or apply a function to each item in an iterable in parallel. Trong phần này, chúng tôi sẽ xem xét một số trường hợp chung mà nó phù hợp, và nơi đó là, sau đó chúng tôi sẽ xem xét các lớp nhiệm vụ rộng và tại sao chúng hoặc không phù hợp với đa xử lý.pool.multiprocessing.Pool. Sử dụng Multiprocessing.Pool khi
Các nhóm xử lý hoạt động tốt nhất khi áp dụng cùng một hàm thuần túy trên một tập hợp các dữ liệu khác nhau (ví dụ: các tác vụ đồng nhất, dữ liệu không đồng nhất). Điều này làm cho mã dễ dàng hơn để đọc và gỡ lỗi. Đây không phải là một quy tắc, chỉ là một gợi ý nhẹ nhàng. Sử dụng nhiều bộ xử lý.pool khi
Các nhóm xử lý có thể hoạt động trên các nhiệm vụ của các loại khác nhau (ví dụ: các nhiệm vụ không đồng nhất), mặc dù nó có thể giúp tổ chức chương trình của bạn và gỡ lỗi dễ dàng nếu một nhóm quy trình riêng biệt chịu trách nhiệm cho từng loại nhiệm vụ. Đây không phải là một quy tắc, chỉ là một gợi ý nhẹ nhàng. Don Tiết sử dụng đa xử lý.pool khi
Điểm ngọt ngào cho các nhóm xử lý là trong việc gửi nhiều nhiệm vụ tương tự, kết quả có thể được sử dụng sau này trong chương trình. Các nhiệm vụ không phù hợp với bản tóm tắt này có lẽ không phù hợp với các nhóm quy trình. Đây không phải là một quy tắc, chỉ là một gợi ý nhẹ nhàng. Don lồng sử dụng các quy trình cho các nhiệm vụ ràng buộc IO (có thể)Bạn có thể sử dụng các quy trình cho các tác vụ ràng buộc IO, mặc dù các chủ đề có thể phù hợp hơn. Nhiệm vụ ràng buộc IO là một loại nhiệm vụ liên quan đến việc đọc từ hoặc ghi vào một thiết bị, tệp hoặc kết nối ổ cắm. Các hoạt động liên quan đến đầu vào và đầu ra (IO) và tốc độ của các hoạt động này bị ràng buộc bởi thiết bị, ổ cứng hoặc kết nối mạng. Đây là lý do tại sao các nhiệm vụ này được gọi là giới hạn IO. CPU thực sự nhanh. CPU hiện đại như 4GHz có thể thực hiện 4 tỷ hướng dẫn mỗi giây và bạn có thể có nhiều hơn một CPU trong hệ thống của mình. Làm IO rất chậm so với tốc độ của CPU. Tương tác với các thiết bị, đọc và ghi các tệp và kết nối ổ cắm liên quan đến việc gọi hướng dẫn trong hệ điều hành của bạn (kernel), sẽ chờ hoàn thành thao tác. Nếu hoạt động này là trọng tâm chính cho CPU của bạn, chẳng hạn như thực hiện trong chuỗi chính của chương trình Python của bạn, thì CPU của bạn sẽ chờ nhiều mili giây hoặc thậm chí nhiều giây không làm gì cả. Đó là có khả năng hàng tỷ hoạt động mà nó được ngăn chặn thực thi. Chúng tôi có thể giải phóng CPU khỏi các hoạt động ràng buộc IO bằng cách thực hiện các hoạt động ràng buộc IO trên một quy trình thực thi khác. Điều này cho phép CPU bắt đầu nhiệm vụ và chuyển nó cho hệ điều hành (kernel) để chờ đợi và giải phóng nó để thực hiện trong một quy trình ứng dụng khác. Có nhiều hơn nữa cho nó dưới vỏ bọc, nhưng đây là ý chính. Do đó, các tác vụ chúng tôi thực thi với một đa xử lý.pool có thể là các nhiệm vụ liên quan đến các hoạt động IO.multiprocessing.Pool can be tasks that involve IO operations. Những ví dụ bao gồm:
Sử dụng các quy trình cho các nhiệm vụ ràng buộc CPUBạn có thể nên sử dụng các quy trình cho các nhiệm vụ liên kết CPU. Nhiệm vụ ràng buộc CPU là một loại nhiệm vụ liên quan đến việc thực hiện tính toán và không liên quan đến IO. Các hoạt động chỉ liên quan đến dữ liệu trong bộ nhớ chính (RAM) hoặc bộ đệm (bộ đệm CPU) và thực hiện các tính toán trên hoặc với dữ liệu đó. Như vậy, giới hạn về các hoạt động này là tốc độ của CPU. Đây là lý do tại sao chúng tôi gọi chúng là các nhiệm vụ ràng buộc CPU. Những ví dụ bao gồm:
Chụp ảnh hoặc ghi video. Và nhiều hơn nữa.multiprocessing.Pool class in Python is probably the best path toward achieving this end. Sử dụng các quy trình cho các nhiệm vụ ràng buộc CPUBạn có thể nên sử dụng các quy trình cho các nhiệm vụ liên kết CPU. Nhiệm vụ ràng buộc CPU là một loại nhiệm vụ liên quan đến việc thực hiện tính toán và không liên quan đến IO. Các hoạt động chỉ liên quan đến dữ liệu trong bộ nhớ chính (RAM) hoặc bộ đệm (bộ đệm CPU) và thực hiện các tính toán trên hoặc với dữ liệu đó. Như vậy, giới hạn về các hoạt động này là tốc độ của CPU. Đây là lý do tại sao chúng tôi gọi chúng là các nhiệm vụ ràng buộc CPU. Tính toán điểm trong một fractal.
Xử lý văn bản. Chạy mô phỏng.CPU rất nhanh và chúng tôi thường có nhiều hơn một CPU. Chúng tôi muốn thực hiện các nhiệm vụ của mình và sử dụng đầy đủ nhiều lõi CPU trong phần cứng hiện đại. Sử dụng các quy trình và nhóm xử lý thông qua lớp đa xử lý.pool trong Python có lẽ là con đường tốt nhất để đạt được kết thúc này.initializer” argument to specify the function name and “initargs” to specify a tuple of arguments to the function. Xử lý ngoại lệ nhóm đa bộ xử lý Xử lý ngoại lệ là một cân nhắc quan trọng khi sử dụng các quy trình.
Nhiệm vụ hoàn thành cuộc gọi lại
Xử lý ngoại lệ trong khởi tạo công nhân Bạn có thể chỉ định chức năng khởi tạo tùy chỉnh khi định cấu hình Multiprocessing.Pool.Pool.
từ đa bộ xử lý.pool Pool # chức năng để khởi tạo quy trình công nhân def init (): & nbsp; & nbsp; & nbsp; & nbsp;# nâng cao một ngoại lệ & nbsp; & nbsp; & nbsp; & nbsp; nâng cao ngoại lệ ('một cái gì đó xấu đã xảy ra!') Một ví dụ bị cắt ngắn của đầu ra được liệt kê dưới đây.
Nâng cao ngoại lệ ('Một cái gì đó xấu đã xảy ra!') Ngoại lệ: Một cái gì đó xấu đã xảy ra!Điều này nhấn mạnh rằng nếu bạn sử dụng chức năng khởi tạo tùy chỉnh, bạn phải xem xét cẩn thận các ngoại lệ có thể được nêu ra và có thể xử lý chúng, nếu không có nguy cơ tất cả các nhiệm vụ phụ thuộc vào nhóm quy trình. Xử lý ngoại lệ trong thực thi nhiệm vụ Một ngoại lệ có thể xảy ra trong khi thực hiện nhiệm vụ của bạn.apply(), map(), or starmap() the exception will be re-raised in the caller. Điều này sẽ khiến nhiệm vụ ngừng thực hiện, nhưng sẽ không phá vỡ nhóm quy trình.apply_async(), map_async(), or starmap_async(), an AsyncResult object will be returned. If a task issued asynchronously raises an exception, it will be caught by the process pool and re-raised if you call get() function in the AsyncResult object in order to get the result. Nếu các tác vụ được phát hành với hàm đồng bộ, chẳng hạn như Ứng dụng (), map () hoặc starmap (), ngoại lệ sẽ được nêu lại trong người gọi.
Xử lý các ngoại lệ trong chức năng nhiệm vụ. Xử lý các trường hợp ngoại lệ khi nhận được kết quả từ các nhiệm vụ.Hãy cùng nhau xem xét kỹ hơn từng cách tiếp cận. Xử lý ngoại lệ trong nhiệm vụNone. Xử lý ngoại lệ trong nhiệm vụ có nghĩa là bạn cần một số cơ chế để cho người nhận kết quả biết rằng điều gì đó bất ngờ đã xảy ra. Điều này có thể thông qua giá trị trả về từ hàm, ví dụ: Không có.
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# Nhận kết quả & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# báo cáo kết quả Chạy ví dụ bắt đầu nhóm quy trình theo bình thường, phát hành nhiệm vụ, sau đó chặn chờ kết quả.apply(), apply_async() and map(). Nhiệm vụ làm tăng một ngoại lệ và kết quả nhận được là một thông báo lỗi. Cách tiếp cận này được làm sạch hợp lý cho mã người nhận và sẽ phù hợp với các tác vụ được ban hành bởi cả hai hàm đồng bộ và không đồng bộ như application (), application_async () và map ().Nó có thể yêu cầu xử lý đặc biệt giá trị trả lại tùy chỉnh cho trường hợp thất bại. Xử lý ngoại lệ bên ngoài nhiệm vụ Một giải pháp thay thế để xử lý ngoại lệ trong nhiệm vụ là để lại trách nhiệm cho người nhận kết quả. Điều này có thể cảm thấy giống như một giải pháp tự nhiên hơn, vì nó phù hợp với phiên bản đồng bộ của cùng một hoạt động, ví dụ: Nếu chúng tôi thực hiện cuộc gọi chức năng trong vòng lặp.Exception, which is then handled by the recipient when issuing the task asynchronously and then attempting to get the result from the returned AsyncResult object.
Chạy ví dụ tạo ra nhóm quy trình và gửi công việc theo bình thường. Nhiệm vụ không thành công với một ngoại lệ, nhóm quy trình bắt được ngoại lệ, lưu trữ nó, sau đó tự nâng nó khi chúng ta gọi hàm get () trong đối tượng Asyncresult.get() function in the AsyncResult object. Người nhận kết quả chấp nhận ngoại lệ và bắt nó, báo cáo một trường hợp thất bại. Cách tiếp cận này cũng sẽ hoạt động cho bất kỳ nhiệm vụ nào được ban hành đồng bộ vào nhóm quy trình. Trong trường hợp này, ngoại lệ được đưa ra bởi nhiệm vụ được bắt bởi nhóm quy trình và được tăng lại trong người gọi khi nhận được kết quả. Ví dụ dưới đây cho thấy việc xử lý một ngoại lệ trong người gọi cho một nhiệm vụ được ban hành đồng bộ.
Chạy ví dụ tạo ra nhóm quy trình và gửi công việc theo bình thường. Nhiệm vụ không thành công với một ngoại lệ, nhóm quy trình bắt được ngoại lệ, lưu trữ nó, sau đó tự nâng nó khi chúng ta gọi hàm get () trong đối tượng Asyncresult. Người nhận kết quả chấp nhận ngoại lệ và bắt nó, báo cáo một trường hợp thất bại. Cách tiếp cận này cũng sẽ hoạt động cho bất kỳ nhiệm vụ nào được ban hành đồng bộ vào nhóm quy trình.Trong trường hợp này, ngoại lệ được đưa ra bởi nhiệm vụ được bắt bởi nhóm quy trình và được tăng lại trong người gọi khi nhận được kết quả.successful() function on the AsyncResult object for tasks issued asynchronously to the process pool. Ví dụ dưới đây cho thấy việc xử lý một ngoại lệ trong người gọi cho một nhiệm vụ được ban hành đồng bộ.True) or whether it failed with an Exception or similar (False). # SuperfastPython.com
Chạy ví dụ tạo và gửi nhiệm vụ theo bình thường. Người nhận chờ nhiệm vụ hoàn thành sau đó kiểm tra một trường hợp không thành công. Sự thất bại của nhiệm vụ được xác định và một thông điệp thích hợp được báo cáo. Xử lý ngoại lệ khi gọi bản đồ ()Chúng tôi có thể phát hành nhiều tác vụ cho nhóm quy trình bằng cách sử dụng phiên bản đồng bộ của hàm map () hoặc starmap ().map() function or starmap(). Một hoặc nhiều nhiệm vụ đã phát hành có thể thất bại, điều này sẽ khiến tất cả các nhiệm vụ được ban hành không thành công vì kết quả sẽ không thể truy cập được. Chúng tôi có thể chứng minh điều này với một ví dụ, được liệt kê dưới đây.
Chạy ví dụ, tạo nhóm quy trình và phát hành 5 nhiệm vụ bằng Map (). Một trong 5 nhiệm vụ thất bại với một ngoại lệ. Ngoại lệ sau đó được tăng lại trong trình gọi thay vì trả về trình lặp qua các giá trị trả về.
Ngoại lệ trên là nguyên nhân trực tiếp của ngoại lệ sau:map(), such as map_async(). Điều này cũng xảy ra khi phát hành các tác vụ bằng các phiên bản không đồng bộ của MAP (), chẳng hạn như MAP_ASYNC ().imap() and imap_unordered(), the exception is not re-raised in the caller until the return value for the specific task that failed is requested from the returned iterator. Nếu chúng tôi phát hành các tác vụ với IMAP () và IMAP_Unordered (), ngoại lệ sẽ không được nêu lại trong trình gọi cho đến khi giá trị trả về cho tác vụ cụ thể không được yêu cầu từ trình lặp được trả về. Các ví dụ này nhấn mạnh rằng nếu MAP () hoặc tương đương được sử dụng để phát hành các nhiệm vụ cho nhóm quy trình, thì các tác vụ nên xử lý các trường hợp ngoại lệ của riêng họ hoặc đủ đơn giản để không được mong đợi.Xử lý ngoại lệ trong các cuộc gọi lại hoàn thành nhiệm vụmultiprocessing.Pool is in callback functions. Một trường hợp cuối cùng chúng ta phải xem xét để xử lý ngoại lệ khi sử dụng đa xử lý.pool nằm trong các chức năng gọi lại.apply_async() or map_async() we can add a callback function to be called with the result of the task or a callback function to call if there was an error in the task. Khi phát hành các tác vụ cho nhóm quy trình không đồng bộ với một cuộc gọi đến application_async () hoặc map_async (), chúng tôi có thể thêm chức năng gọi lại để được gọi với kết quả của tác vụ hoặc chức năng gọi lại để gọi nếu có lỗi trong tác vụ.
Ngoại lệ trên là nguyên nhân trực tiếp của ngoại lệ sau:
Nếu chúng tôi phát hành các tác vụ với IMAP () và IMAP_Unordered (), ngoại lệ sẽ không được nêu lại trong trình gọi cho đến khi giá trị trả về cho tác vụ cụ thể không được yêu cầu từ trình lặp được trả về. Các ví dụ này nhấn mạnh rằng nếu MAP () hoặc tương đương được sử dụng để phát hành các nhiệm vụ cho nhóm quy trình, thì các tác vụ nên xử lý các trường hợp ngoại lệ của riêng họ hoặc đủ đơn giản để không được mong đợi. Xử lý ngoại lệ trong các cuộc gọi lại hoàn thành nhiệm vụ Một trường hợp cuối cùng chúng ta phải xem xét để xử lý ngoại lệ khi sử dụng đa xử lý.pool nằm trong các chức năng gọi lại.
Chạy ví dụ bắt đầu nhóm quy trình theo bình thường và phát hành nhiệm vụ. Khi hoàn thành tác vụ, chức năng gọi lại được gọi là thất bại với một ngoại lệ được nâng cao. Chủ đề trợ giúp (Chủ đề-3 trong trường hợp này) thư giãn và phanh nhóm quy trình. Người gọi trong luồng chính của quy trình chính sau đó chờ đợi mãi mãi cho kết quả. Lưu ý, bạn phải chấm dứt chương trình một cách mạnh mẽ bằng cách nhấn Control-C.
Điều này nhấn mạnh rằng nếu các cuộc gọi lại dự kiến sẽ tăng một ngoại lệ, thì nó phải được xử lý rõ ràng nếu không nó sẽ khiến toàn bộ nhóm quy trình gặp rủi ro. Đa bộ xử lý nhóm vs ProcessPoolExecortTrong phần này, chúng tôi sẽ xem xét cách lớp nhóm so sánh với lớp nhóm dựa trên quy trình khác của Python, được gọi là ProcessPoolExecutor.Pool class compares to Python’s other process-based pool class called the ProcessPoolExecutor. ProcessPoolExecutor là gìCác lớp đồng thời.concurrent.futures.ProcessPoolExecutor class provides a process pool in Python. Một quy trình là một ví dụ của một chương trình máy tính. Một quy trình có một luồng thực thi chính và có thể có các luồng bổ sung. Một quá trình cũng có thể sinh sản hoặc nĩa quy trình con. Trong Python, giống như nhiều ngôn ngữ lập trình hiện đại, các quy trình được tạo và quản lý bởi hệ điều hành cơ bản. Bạn có thể tạo một nhóm quy trình bằng cách khởi tạo lớp và chỉ định số lượng quy trình thông qua đối số MAX_Workers; Ví dụ:max_workers argument; for example:
Điều này nhấn mạnh rằng nếu các cuộc gọi lại dự kiến sẽ tăng một ngoại lệ, thì nó phải được xử lý rõ ràng nếu không nó sẽ khiến toàn bộ nhóm quy trình gặp rủi ro.map() and the submit() functions. Đa bộ xử lý nhóm vs ProcessPoolExecortmap() function matches the built-in map() function and takes a function name and an iterable of items. The target function will then be called for each item in the iterable as a separate task in the process pool. An iterable of results will be returned if the target function returns a value. Trong phần này, chúng tôi sẽ xem xét cách lớp nhóm so sánh với lớp nhóm dựa trên quy trình khác của Python, được gọi là ProcessPoolExecutor.map() does not block, but each result yielded in the returned iterator will block until the associated task is completed. ProcessPoolExecutor là gì
Trong phần này, chúng tôi sẽ xem xét cách lớp nhóm so sánh với lớp nhóm dựa trên quy trình khác của Python, được gọi là ProcessPoolExecutor.submit() function that takes the target function name and any arguments and returns a Future object. ProcessPoolExecutor là gìFuture object can be used to query the status of the task (e.g. done(), running(), or cancelled()) and can be used to get the result or exception raised by the task once completed. The calls to result() and exception() will block until the task associated with the Future is done. ProcessPoolExecutor là gì
Đa bộ xử lý nhóm vs ProcessPoolExecortshutdown() function in order to release all of the worker processes and their resources. ProcessPoolExecutor là gì
Điều này nhấn mạnh rằng nếu các cuộc gọi lại dự kiến sẽ tăng một ngoại lệ, thì nó phải được xử lý rõ ràng nếu không nó sẽ khiến toàn bộ nhóm quy trình gặp rủi ro.shutdown() function. ProcessPoolExecutor là gì
Bạn có thể tạo một nhóm quy trình bằng cách khởi tạo lớp và chỉ định số lượng quy trình thông qua đối số MAX_Workers; Ví dụ:ProcessPoolExecutor, see the guide:
Sau đó, bạn có thể gửi các tác vụ để được thực hiện bởi nhóm quy trình bằng các hàm bản đồ () và trình gửi ().multiprocessing.Pool and ProcessPoolExecutor, let’s compare and contrast each. Sự tương đồng giữa Pool và ProcessPoolExecutorCác lớp đa xử lý.Pool và ProcessPoolExecutor rất giống nhau. Cả hai đều là nhóm quy trình của các quy trình lao động trẻ em.multiprocessing.Pool and ProcessPoolExecutor classes are very similar. They are both process pools of child worker processes. Những điểm tương đồng quan trọng nhất như sau:
Hãy cùng nhau xem xét kỹ hơn từng cái. 1. Cả hai quy trình sử dụngCả đa xử lý.Pool và ProcessPoolExecutor đều tạo và sử dụng các quy trình nhân viên trẻ em.multiprocessing.Pool and ProcessPoolExecutor create and use child worker processes. Đây là những quá trình con ở cấp độ tự nhiên hoặc hệ thống thực sự có thể bị rẽ nhánh hoặc sinh sản. Điều này có nghĩa là, chúng được tạo và quản lý bởi hệ điều hành cơ bản. Do đó, các quy trình con công nhân được sử dụng trong mỗi lớp cung cấp song song thực sự thông qua đồng thời dựa trên quy trình. Điều này có nghĩa là các nhiệm vụ được cấp cho mỗi nhóm quy trình sẽ thực hiện đồng thời và sử dụng tốt nhất các lõi CPU có sẵn. Điều đó cũng có nghĩa là, các nhiệm vụ được cấp cho mỗi nhóm quy trình sẽ phải chịu sự giao tiếp giữa các quá trình, yêu cầu dữ liệu được gửi đến các quy trình con và nhận được từ các quy trình con phải được ngâm, thêm chi phí tính toán. 2. Cả hai đều có thể chạy các tác vụ ad hocCả Multiprocessing.Pool và ProcessPoolExecutor đều có thể được sử dụng để thực hiện các tác vụ ad hoc được xác định bởi các chức năng tùy chỉnh.multiprocessing.Pool and ProcessPoolExecutor may be used to execute ad hoc tasks defined by custom functions. Đa xử lý.pool có thể phát hành các tác vụ một lần bằng hàm application () và application_async () và có thể phát hành nhiều tác vụ sử dụng cùng một hàm với các đối số khác nhau với bản đồ (), imap (), imap_unordered () và starmap () Các chức năng và các tương đương không đồng bộ của chúng map_async () và starmap_async ().multiprocessing.Pool can issue one-off tasks using the apply() and apply_async() function, and may issue multiple tasks that use the same function with different arguments with the map(), imap(), imap_unordered(), and starmap() functions and their asynchronous equivalents map_async() and starmap_async(). ProcessPoolExecutor có thể phát hành các tác vụ một lần thông qua hàm SOUNT () và có thể phát hành nhiều tác vụ sử dụng cùng một hàm với các đối số khác nhau thông qua hàm map ().ProcessPoolExecutor can issue one-off tasks via the submit() function, and may issue multiple tasks that use the same function with different arguments via the map() function. 3. Cả hai đều hỗ trợ các nhiệm vụ không đồng bộCả hai bộ xử lý.Pool và ProcessPoolExecutor đều có thể được sử dụng để ban hành các nhiệm vụ không đồng bộ.multiprocessing.Pool and ProcessPoolExecutor can be used to issue tasks asynchronously. Hãy nhớ lại rằng việc ban hành các nhiệm vụ không đồng bộ có nghĩa là quá trình chính có thể ban hành một nhiệm vụ mà không bị chặn. Cuộc gọi chức năng sẽ quay lại ngay lập tức với một số xử lý trong nhiệm vụ đã phát hành và cho phép quy trình chính tiếp tục với chương trình. Đa xử lý.Pool hỗ trợ các tác vụ phát hành không đồng bộ thông qua các hàm application_async (), map_async () và starmap_async () trả về một đối tượng không đồng bộ cung cấp xử lý các tác vụ đã phát hành.multiprocessing.Pool supports issuing tasks asynchronously via the apply_async(), map_async() and starmap_async() functions that return an AsyncResult object that provides a handle on the issued tasks. ProcessPoolExecutor cung cấp chức năng gửi () để phát hành các tác vụ không đồng bộ mà trả về một đối tượng trong tương lai cung cấp một xử lý cho nhiệm vụ đã phát hành.ProcessPoolExecutor provides the submit() function for issuing tasks asynchronously that returns a Future object that provides a handle on the issued task. Ngoài ra, cả hai nhóm quy trình cung cấp các cơ chế hữu ích để làm việc với các tác vụ không đồng bộ, chẳng hạn như kiểm tra trạng thái của chúng, nhận kết quả và thêm các chức năng gọi lại. 4. Cả hai có thể chờ tất cả các nhiệm vụCả đa xử lý.Pool và ProcessPoolExecutor đều cung cấp khả năng chờ đợi các nhiệm vụ được ban hành không đồng bộ.multiprocessing.Pool and ProcessPoolExecutor provide the ability to wait for tasks that were issued asynchronously. Đa xử lý.Pool cung cấp hàm chờ () trên đối tượng Asyncresult được trả về dưới dạng xử lý các tác vụ không đồng bộ. Nó cũng cho phép nhóm được tắt và tham gia, điều này sẽ không trở lại cho đến khi tất cả các nhiệm vụ được phát hành đã hoàn thành.multiprocessing.Pool provides a wait() function on the AsyncResult object returned as a handle on asynchronous tasks. It also allows the pool to be shutdown and joined, which will not return until all issued tasks have completed. ProcessPoolExecutor cung cấp chức năng mô -đun Wait () có thể lấy một bộ sưu tập các đối tượng trong tương lai để chờ đợi. Nó cũng cho phép nhóm quy trình tắt, có thể được cấu hình để chặn cho đến khi tất cả các tác vụ trong nhóm đã hoàn thành.ProcessPoolExecutor provides the wait() module function that can take a collection of Future objects on which to wait. It also allows the process pool to be shutdown, which can be configured to block until all tasks in the pool have completed. 5. Cả hai đều có tương đương dựa trên chủ đềCả hai nhóm quy trình đa xử lý.Pool và ProcessPoolExecutor đều có các tương đương dựa trên luồng.multiprocessing.Pool and ProcessPoolExecutor process pools have thread-based equivalents. Multiprocessing.pool có đa xử lý.Pool.ThreadPool cung cấp cùng một API, ngoại trừ việc nó sử dụng đồng thời dựa trên luồng thay vì đồng thời dựa trên quy trình.multiprocessing.Pool has the multiprocessing.pool.ThreadPool which provides the same API, except that it uses thread-based concurrency instead of process-based concurrency. Tương tự, ProcessPoolExecutor có đồng thời.ProcessPoolExecutor has the concurrent.futures.ThreadPoolExecutor that provides the same API as the ProcessPoolExecutor (e.g. extends the same Executor base class) except that it is implemented using thread-based concurrency. Điều này rất hữu ích vì cả hai nhóm quy trình có thể được sử dụng và chuyển sang sử dụng đồng thời dựa trên luồng với rất ít thay đổi đối với mã chương trình. Sự khác biệt giữa Pool và ProcessPoolExecutorĐa xử lý.Pool và ProcessPoolExecutor cũng khác nhau một cách tinh tế.multiprocessing.Pool and ProcessPoolExecutor are also subtly different. Sự khác biệt giữa hai nhóm quy trình này tập trung vào sự khác biệt trong API trên chính các lớp. Chúng tôi khác biệt chính như sau:
Hãy cùng nhau xem xét kỹ hơn từng cái. 1. Cả hai quy trình sử dụngCả đa xử lý.Pool và ProcessPoolExecutor đều tạo và sử dụng các quy trình nhân viên trẻ em.ProcessPoolExecutor can be canceled, whereas tasks issued to the multiprocessing.Pool cannot. ProcessPoolExecutor cung cấp khả năng hủy các tác vụ đã được cấp cho nhóm quy trình nhưng chưa bắt đầu thực thi.ProcessPoolExecutor provides the ability to cancel tasks that have been issued to the process pool but have not yet started executing. Điều này được cung cấp thông qua hàm hủy () trên đối tượng trong tương lai được trả về từ việc ban hành một nhiệm vụ thông qua gửi ().cancel() function on the Future object returned from issuing a task via submit(). Đa xử lý.pool không cung cấp khả năng này.multiprocessing.Pool does not provide this capability. 2. Hoạt động trên các nhóm nhiệm vụProcessPoolExecutor cung cấp các công cụ để làm việc với các nhóm tác vụ không đồng bộ, trong khi đó, đa xử lý.pool thì không.ProcessPoolExecutor provides tools to work with groups of asynchronous tasks, whereas the multiprocessing.Pool does not. Mô -đun đồng thời. Các chức năng này được thiết kế để hoạt động với các bộ sưu tập các đối tượng trong tương lai được trả về khi phát hành các tác vụ không đồng bộ vào nhóm quy trình thông qua hàm gửi ().concurrent.futures module provides the wait() and as_completed() module functions. These functions are designed to work with collections of Future objects returned when issuing tasks asynchronously to the process pool via the submit() function. Họ cho phép người gọi chờ một sự kiện trên một bộ sưu tập các nhiệm vụ không đồng nhất trong nhóm quy trình, chẳng hạn như tất cả các nhiệm vụ hoàn thành, để nhiệm vụ đầu tiên hoàn thành hoặc cho nhiệm vụ đầu tiên thất bại. Họ cũng cho phép người gọi xử lý kết quả từ một tập hợp các nhiệm vụ không đồng nhất theo thứ tự các nhiệm vụ được hoàn thành, thay vì lệnh mà các nhiệm vụ được ban hành. Đa xử lý.pool không cung cấp khả năng này.multiprocessing.Pool does not provide this capability. 2. Hoạt động trên các nhóm nhiệm vụProcessPoolExecutor cung cấp các công cụ để làm việc với các nhóm tác vụ không đồng bộ, trong khi đó, đa xử lý.pool thì không.multiprocessing.Pool provides the ability to forcefully terminate all tasks, whereas the ProcessPoolExecutor does not. Mô -đun đồng thời. Các chức năng này được thiết kế để hoạt động với các bộ sưu tập các đối tượng trong tương lai được trả về khi phát hành các tác vụ không đồng bộ vào nhóm quy trình thông qua hàm gửi ().multiprocessing.Pool class provides the close() and terminate() functions that will send the SIGTERM and SIGKILL signals to the child worker processes. Họ cho phép người gọi chờ một sự kiện trên một bộ sưu tập các nhiệm vụ không đồng nhất trong nhóm quy trình, chẳng hạn như tất cả các nhiệm vụ hoàn thành, để nhiệm vụ đầu tiên hoàn thành hoặc cho nhiệm vụ đầu tiên thất bại. Họ cũng cho phép người gọi xử lý kết quả từ một tập hợp các nhiệm vụ không đồng nhất theo thứ tự các nhiệm vụ được hoàn thành, thay vì lệnh mà các nhiệm vụ được ban hành.ProcessPoolExecutor does not provide this capability. 3. Khả năng chấm dứt tất cả các nhiệm vụĐa xử lý.pool cung cấp khả năng chấm dứt mạnh mẽ tất cả các tác vụ, trong khi ProcessPoolExecutor thì không.multiprocessing.Pool provides a focus on map() based concurrency, whereas the ProcessPoolExecutor does not. Lớp đa xử lý.Pool cung cấp các hàm đóng () và chấm dứt () sẽ gửi tín hiệu Sigterm và Sigkill đến các quy trình nhân viên trẻ em.ProcessPoolExecutor does provide a parallel version of the built-in map() function which will apply the same function to an iterable of arguments. Each function call is issued as a separate task to the process pool. Những tín hiệu này sẽ khiến các quy trình nhân viên trẻ em dừng lại, ngay cả khi chúng ở giữa việc thực hiện các nhiệm vụ, có thể rời khỏi trạng thái chương trình ở trạng thái không nhất quán.multiprocessing.Pool provides three versions of the built-in map() function for applying the same function to an iterable of arguments in parallel as tasks in the process pool. Tuy nhiên, ProcessPoolExecutor không cung cấp khả năng này.map(), a lazier version of map() called imap(), and a version of map() that takes multiple arguments for each function call called starmap(). 4. Các chức năng bản đồ không đồng bộimap() where the iterable of results has return values in the order that tasks complete rather than the order that tasks are issued called imap_unordered(). Đa xử lý.pool cung cấp một trọng tâm vào đồng thời dựa trên bản đồ (), trong khi ProcessPoolExecutor thì không.map() function called map_async() and of the starmap() function called starmap_async(). Quá trình xử lý đó cung cấp một phiên bản song song của hàm Bản đồ tích hợp () sẽ áp dụng chức năng tương tự cho một đối số có thể lặp lại. Mỗi cuộc gọi chức năng được ban hành như một nhiệm vụ riêng cho nhóm quy trình.multiprocessing.Pool provides 6 parallel versions of the built-in map() function. Đa xử lý.pool cung cấp ba phiên bản của hàm Bản đồ tích hợp () để áp dụng cùng một hàm cho một đối số có thể lặp lại song song như các tác vụ trong nhóm quy trình.Chúng là: bản đồ (), một phiên bản lười biếng hơn của map () được gọi là imap () và phiên bản map () có nhiều đối số cho mỗi cuộc gọi hàm gọi là starmap ().ProcessPoolExecutor provides a way to access an exception raised in an asynchronous task directly, whereas the multiprocessing.Pool does not. Nó cũng cung cấp một phiên bản IMAP () trong đó có thể lặp lại kết quả có các giá trị trả về theo thứ tự các tác vụ hoàn thành thay vì thứ tự các tác vụ được phát hành gọi là imap_unordered (). Cuối cùng, nó có các phiên bản không đồng bộ của hàm map () có tên MAP_ASYNC () và của hàm starmap () được gọi là starmap_async ().ProcessPoolExecutor provides the ability to directly get an exception raised in a task. Trong tất cả, đa xử lý.pool cung cấp 6 phiên bản song song của hàm bản đồ tích hợp ().ProcessPoolExecutor asynchronously via the submit() function will return a Future object. The exception() function on the Future object allows the caller to check if an exception was raised in the task, and if so, to access it directly. 5. Khả năng truy cập ngoại lệmultiprocessing.Pool does not provide this ability. ProcessPoolExecutor cung cấp một cách để truy cập một ngoại lệ được nêu trực tiếp trong một tác vụ không đồng bộ trực tiếp, trong khi đó, đa xử lý.pool thì không.Cả hai nhóm xử lý đều cung cấp khả năng kiểm tra xem một nhiệm vụ có thành công hay không, và sẽ tìm lại một ngoại lệ khi nhận được kết quả nhiệm vụ, nếu một ngoại lệ được nêu ra và không được xử lý trong nhiệm vụ.multiprocessing.Pool and ProcessPoolExecutor. multiprocessing.Pool
Không cung cấp khả năng hủy bỏ các tác vụ, trong khi ProcessPoolExecutor.
Hình dưới đây cung cấp một so sánh cạnh nhau hữu ích về sự khác biệt chính giữa đa xử lý.Pool và ProcessPoolExecutor.multiprocessing.Pool and ProcessPoolExecutor. Sự khác biệt giữa đa xử lý.Pool và ProcessPoolExecutorBộ xử lý đa xử lý thực hành tốt nhấtBây giờ chúng ta đã biết cách thức đa xử lý.pool hoạt động và cách sử dụng nó, hãy để xem xét một số thực tiễn tốt nhất để xem xét khi đưa các nhóm quy trình vào các chương trình Python của chúng tôi.multiprocessing.Pool works and how to use it, let’s review some best practices to consider when bringing process pools into our Python programs. Để giữ cho mọi thứ đơn giản, có năm thực hành tốt nhất; họ đang:
Hãy để bắt đầu với thực tiễn đầu tiên, đó là sử dụng Trình quản lý bối cảnh. Thực hành 1: Sử dụng Trình quản lý bối cảnhThực hành 2: Sử dụng bản đồ () cho các vòng lặp song song Thực hành 3: Sử dụng imap_unordered () cho mã đáp ứng
Sử dụng trình quản lý bối cảnh khi sử dụng nhóm đa xử lý để đảm bảo nhóm luôn được đóng đúng. Ví dụ:close() or terminate(). ...
Hãy để bắt đầu với thực tiễn đầu tiên, đó là sử dụng Trình quản lý bối cảnh. Sử dụng trình quản lý bối cảnh khi sử dụng nhóm đa xử lý để đảm bảo nhóm luôn được đóng đúng.
Thực hành 2: Sử dụng bản đồ () cho các vòng lặp song songThực hành 3: Sử dụng imap_unordered () cho mã đáp ứngmap() function to dispatch all tasks and process results once all tasks are completed. Thực hành 4: Sử dụng map_async () để ban hành các nhiệm vụ không đồng bộtask() for each item:
Sử dụng trình quản lý bối cảnh khi sử dụng nhóm đa xử lý để đảm bảo nhóm luôn được đóng đúng.map() function:
Sử dụng trình quản lý bối cảnh khi sử dụng nhóm đa xử lý để đảm bảo nhóm luôn được đóng đúng.map() function on the process pool.
Sử dụng trình quản lý bối cảnh khi sử dụng nhóm đa xử lý để đảm bảo nhóm luôn được đóng đúng.map() function if your target task function has side effects. Ví dụ:map() function if your target task function has no arguments or more than one argument. If you have multiple arguments, you can use the starmap() function instead. ...map() function if you need control over exception handling for each task, or if you would like to get results to tasks in the order that tasks are completed. # Tạo một nhóm quy trình thông qua Trình quản lý bối cảnhmap() function if you have many tasks (e.g. hundreds or thousands) as all tasks will be dispatched at once. Instead, consider the more lazy imap() function. với Pool (4) Aspool:map() with the multiprocessing pool in the tutorial:
Thực hành 3: Sử dụng imap_unordered () cho mã đáp ứngThực hành 4: Sử dụng map_async () để ban hành các nhiệm vụ không đồng bộimap_unordered() function. Thực hành 5: Sử dụng các chức năng độc lập làm nhiệm vụPool.map() function, the Pool.imap_unordered() function will iterate the provided iterable one item at a time and issue tasks to the process pool. Thực hành 6: Sử dụng cho các nhiệm vụ ràng buộc CPU (có thể)Pool.imap() function, the Pool.imap_unordered() function will yield return values in the order that tasks are completed, not the order that tasks were issued to the process pool. Hãy để bắt đầu với thực tiễn đầu tiên, đó là sử dụng Trình quản lý bối cảnh. Thực hành 3: Sử dụng imap_unordered () cho mã đáp ứng
Không sử dụng hàm imap_unordered () nếu bạn cần xử lý kết quả theo thứ tự các tác vụ được gửi đến nhóm quy trình, thay vào đó, sử dụng hàm map ().imap_unordered() function if you need to process the results in the order that the tasks were submitted to the process pool, instead, use map() function. Không sử dụng hàm imap_unordered () Nếu bạn cần kết quả từ tất cả các tác vụ trước khi tiếp tục tham gia chương trình, thay vào đó, bạn có thể tốt hơn khi sử dụng hàm map_async () và hàm asyncresult.wait ().imap_unordered() function if you need results from all tasks before continuing on in the program, instead, you may be better off using map_async() and the AsyncResult.wait() function. Không sử dụng hàm imap_unordered () cho một vòng lặp song song đơn giản, thay vào đó, bạn có thể tốt hơn khi sử dụng map ().imap_unordered() function for a simple parallel for-loop, instead, you may be better off using map(). Bạn có thể tìm hiểu thêm về hàm imap_unordered () trong hướng dẫn:imap_unordered() function in the tutorial:
Thực hành 4: Sử dụng map_async () để ban hành các nhiệm vụ không đồng bộNếu bạn cần đưa ra nhiều nhiệm vụ không đồng bộ, ví dụ: FIRE-and-FORGE Sử dụng hàm map_async ().map_async() function. Hàm map_async () không chặn trong khi hàm được áp dụng cho từng mục trong ITEBLE, thay vào đó, nó trả về một đối tượng không đồng bộ mà từ đó kết quả có thể được truy cập.map_async() function does not block while the function is applied to each item in the iterable, instead it returns a AsyncResult object from which the results may be accessed. Vì map_async () không chặn, nó cho phép người gọi tiếp tục và truy xuất kết quả khi cần.map_async() does not block, it allows the caller to continue and retrieve the result when needed. Người gọi có thể chọn gọi hàm Wait () trên đối tượng Asyncresult đã trả về để chờ tất cả các tác vụ đã phát hành hoàn thành hoặc gọi hàm get () .wait() function on the returned AsyncResult object in order to wait for all of the issued tasks to complete, or call the get() function to wait for the task to complete and access an iterable of return values. Ví dụ:
Không sử dụng hàm map_async () nếu bạn muốn phát hành các tác vụ và sau đó xử lý kết quả sau khi tất cả các tác vụ hoàn tất. Bạn sẽ tốt hơn khi sử dụng hàm map ().map_async() function if you want to issue the tasks and then process the results once all tasks are complete. You would be better off using the map() function. Không sử dụng hàm map_async () nếu bạn muốn ban hành các tác vụ từng người một cách lười biếng để bảo tồn bộ nhớ, thay vào đó sử dụng hàm imap ().map_async() function if you want to issue tasks one-by-one in a lazy manner in order to conserve memory, instead use the imap() function. Không sử dụng hàm map_async () nếu bạn muốn ban hành các tác vụ thực hiện nhiều đối số, thay vào đó sử dụng hàm starmap_async ().map_async() function if you wish to issue tasks that take multiple arguments, instead use the starmap_async() function. Bạn có thể tìm hiểu thêm về hàm map_async () trong hướng dẫn:map_async() function in the tutorial:
Thực hành 5: Sử dụng các chức năng độc lập làm nhiệm vụSử dụng nhóm đa xử lý nếu các nhiệm vụ của bạn độc lập. Điều này có nghĩa là mỗi nhiệm vụ không phụ thuộc vào các nhiệm vụ khác có thể thực thi cùng một lúc. Nó cũng có thể có nghĩa là các tác vụ không phụ thuộc vào bất kỳ dữ liệu nào ngoài dữ liệu được cung cấp thông qua các đối số chức năng cho tác vụ. Nhóm đa xử lý là lý tưởng cho các tác vụ không thay đổi bất kỳ dữ liệu nào, ví dụ: Không có tác dụng phụ, được gọi là các chức năng thuần túy. Nhóm đa xử lý có thể được tổ chức thành các luồng dữ liệu và đường ống cho sự phụ thuộc tuyến tính giữa các tác vụ, có lẽ với một nhóm đa xử lý cho mỗi loại tác vụ. Nhóm đa xử lý không được thiết kế cho các nhiệm vụ yêu cầu phối hợp, bạn nên xem xét sử dụng lớp đa xử lý. Lớp xử lý và các mẫu phối hợp như rào cản và semaphore.Barrier and Semaphore. Các nhóm quy trình không được thiết kế cho các tác vụ yêu cầu đồng bộ hóa, bạn nên xem xét sử dụng lớp đa xử lý. Lớp xử lý và các mẫu khóa như Lock và Rlock thông qua Trình quản lý.multiprocessing.Process class and locking patterns like Lock and RLock via a Manager. Thực hành 6: Sử dụng cho các nhiệm vụ ràng buộc CPU (có thể)Nhóm đa xử lý có thể được sử dụng cho các nhiệm vụ ràng buộc IO và các tác vụ gắn CPU. Tuy nhiên, có lẽ nó phù hợp nhất với các tác vụ gắn CPU, trong khi phần đa xử lý.pool.ThreadPool hoặc ThreadPoolExecutor có lẽ phù hợp nhất cho các nhiệm vụ gắn IO.multiprocessing.pool.ThreadPool or ThreadPoolExecutor are probably best suited for IO-bound tasks. Các nhiệm vụ ràng buộc CPU là những nhiệm vụ liên quan đến tính toán trực tiếp, ví dụ: Thực hiện hướng dẫn trên dữ liệu trong CPU. Chúng bị ràng buộc bởi tốc độ thực hiện CPU, do đó tên CPU bị ràng buộc. Điều này không giống như các tác vụ ràng buộc IO phải chờ trên các tài nguyên bên ngoài như đọc hoặc ghi vào hoặc từ các kết nối và tệp mạng. Ví dụ về các nhiệm vụ liên kết CPU phổ biến có thể phù hợp với đa xử lý.Pool bao gồm:
Đa xử lý.pool có thể được sử dụng cho các tác vụ ràng buộc IO, nhưng nó có thể là một phù hợp hơn so với sử dụng các luồng và đa xử lý.pool.ThreadPool.multiprocessing.Pool can be used for IO bound tasks, but it is probably a less well fit compared to using threads and the multiprocessing.pool.ThreadPool. Điều này là do hai lý do:
Số lượng quy trình bạn có thể tạo và quản lý thường khá hạn chế, chẳng hạn như hàng chục hoặc dưới 100. Trong khi đó, khi bạn đang sử dụng các luồng, bạn có thể có hàng trăm luồng hoặc thậm chí hàng ngàn luồng trong một quy trình. Điều này rất hữu ích cho các hoạt động IO mà nhiều người cần truy cập hoặc quản lý một số lượng lớn các kết nối hoặc tài nguyên đồng thời. Điều này có thể được đẩy đến hàng chục ngàn kết nối hoặc tài nguyên hoặc thậm chí cao hơn khi sử dụng Asyncio. Các tác vụ ràng buộc IO thường liên quan đến việc đọc hoặc viết nhiều dữ liệu. Đây có thể là dữ liệu được đọc hoặc viết từ hoặc đến các kết nối từ xa, cơ sở dữ liệu, máy chủ, tệp, thiết bị bên ngoài, v.v. Do đó, nếu dữ liệu cần được chia sẻ giữa các quy trình, chẳng hạn như trong một đường ống, có thể yêu cầu dữ liệu được tuần tự hóa (được gọi là ngâm, quá trình tuần tự hóa Python tích hợp) để chuyển từ quy trình này sang quy trình khác. Điều này có thể chậm và rất nhiều bộ nhớ, đặc biệt là đối với một lượng lớn dữ liệu. Đây không phải là trường hợp khi sử dụng các luồng có thể chia sẻ và truy cập cùng một tài nguyên trong bộ nhớ mà không cần tuần tự hóa dữ liệu. Các lỗi phổ biến khi sử dụng nhóm đa xử lýCó một số lỗi phổ biến khi sử dụng đa xử lý.pool.multiprocessing.Pool. Các lỗi này thường được thực hiện do các lỗi được giới thiệu bởi mã sao chép và thực hiện hoặc từ một sự hiểu lầm nhẹ về cách thức đa xử lý.pool hoạt động. Chúng tôi sẽ xem xét kỹ hơn một số lỗi phổ biến hơn khi sử dụng đa xử lý.pool, chẳng hạn như:multiprocessing.Pool, such as:
Hãy cùng nhau xem xét kỹ hơn từng cái. Lỗi 1: Quên __main__LRI 2: Sử dụng lệnh gọi hàm trong SUMMT ()Pool is forgetting to protect the entry point, e.g. check for the __main__ module. Lỗi 3: Sử dụng lệnh gọi hàm trong bản đồ ()Process class or the multiprocessing.Pool class we must include a check for the top-level environment. This is specifically the case when using the ‘spawn‘ start method, the default on Win32 and MacOS, but is a good practice anyway. Lỗi 4: Chữ ký chức năng không chính xác cho MAP ()__name__ is equal to the string ‘__main__‘. Lỗi 5: Chữ ký chức năng không chính xác cho cuộc gọi lại Lỗi 6: Đối số hoặc dữ liệu được chia sẻ không hấp dẫn
Cho đến nay, lỗi lớn nhất khi sử dụng nhóm đa xử lý là quên bảo vệ điểm vào, ví dụ: Kiểm tra mô -đun __main__.__main__ more generally here:
Chúng ta có thể kiểm tra môi trường cấp cao nhất bằng cách kiểm tra xem có biến tên mô-đun __name__ bằng chuỗi ‘__main__‘ không. Điều này chỉ ra rằng mã đang chạy ở môi trường mã cấp cao nhất, thay vì được nhập bởi một chương trình hoặc tập lệnh.multiprocessing.Pool without a check for the __main__ module is listed below.
# Nhiệm vụ tùy chỉnh sẽ ngủ trong một khoảng thời gian thay đổiRuntimeError.
& nbsp; & nbsp; & nbsp; & nbsp;# Gửi tất cả các nhiệm vụ
Chạy ví dụ này sẽ thất bại với RunTimEError.Traceback (cuộc gọi gần đây nhất cuối cùng):apply_async() function. Lỗi 6: Đối số hoặc dữ liệu được chia sẻ không hấp dẫn
với pool () aspool:
Chạy ví dụ này sẽ thất bại với một lỗi.
Ngoại lệ trên là nguyên nhân trực tiếp của ngoại lệ sau:apply_async() to take the name of your function and any arguments, instead of calling the function in the call to execute. Bạn có thể sửa lỗi bằng cách cập nhật cuộc gọi lên application_async () để lấy tên của chức năng và bất kỳ đối số nào, thay vì gọi hàm trong cuộc gọi để thực thi.
Ngoại lệ trên là nguyên nhân trực tiếp của ngoại lệ sau:Bạn có thể sửa lỗi bằng cách cập nhật cuộc gọi lên application_async () để lấy tên của chức năng và bất kỳ đối số nào, thay vì gọi hàm trong cuộc gọi để thực thi.map() function. Bạn có thể sửa lỗi bằng cách cập nhật cuộc gọi lên application_async () để lấy tên của chức năng và bất kỳ đối số nào, thay vì gọi hàm trong cuộc gọi để thực thi.
Bạn có thể sửa lỗi bằng cách cập nhật cuộc gọi lên application_async () để lấy tên của chức năng và bất kỳ đối số nào, thay vì gọi hàm trong cuộc gọi để thực thi.
& nbsp; & nbsp; & nbsp; & nbsp;# block trong giây látTypeError.
& nbsp; & nbsp; & nbsp; & nbsp;# bắt đầu nhóm quy trìnhmap() to pass the name of the target task function instead of a call to the function.
Bạn có thể sửa lỗi bằng cách cập nhật cuộc gọi lên application_async () để lấy tên của chức năng và bất kỳ đối số nào, thay vì gọi hàm trong cuộc gọi để thực thi.Ví dụ:map() is to provide no second argument to the function, e.g. the iterable. Bạn có thể sửa lỗi bằng cách cập nhật cuộc gọi lên application_async () để lấy tên của chức năng và bất kỳ đối số nào, thay vì gọi hàm trong cuộc gọi để thực thi.
Bạn có thể sửa lỗi bằng cách cập nhật cuộc gọi lên application_async () để lấy tên của chức năng và bất kỳ đối số nào, thay vì gọi hàm trong cuộc gọi để thực thi.
& nbsp; & nbsp; & nbsp; & nbsp;# block trong giây látmap() function to iterate over. & nbsp; & nbsp; & nbsp; & nbsp;# block trong giây látTypeError.
# Bảo vệ điểm vàomap() along with your function name.
Bạn có thể sửa lỗi bằng cách cập nhật cuộc gọi lên application_async () để lấy tên của chức năng và bất kỳ đối số nào, thay vì gọi hàm trong cuộc gọi để thực thi.Ví dụ: Bạn có thể sửa lỗi bằng cách cập nhật cuộc gọi lên application_async () để lấy tên của chức năng và bất kỳ đối số nào, thay vì gọi hàm trong cuộc gọi để thực thi.
Bạn có thể sửa lỗi bằng cách cập nhật cuộc gọi lên application_async () để lấy tên của chức năng và bất kỳ đối số nào, thay vì gọi hàm trong cuộc gọi để thực thi.
Chạy ví dụ này sẽ dẫn đến một lỗi khi cuộc gọi lại được gọi bởi nhóm quy trình. Điều này sẽ phá vỡ nhóm quy trình và chương trình sẽ phải bị giết thủ công bằng một điều khiển-C.
Sửa lỗi này liên quan đến việc cập nhật chữ ký của chức năng gọi lại của bạn để bao gồm kết quả từ tác vụ.
Bạn có thể tìm hiểu thêm về việc sử dụng các chức năng gọi lại với các tác vụ không đồng bộ trong hướng dẫn:
Lỗi này cũng có thể xảy ra với cuộc gọi lại lỗi và quên thêm lỗi làm đối số trong hàm gọi lại lỗi. Lỗi 6: Đối số hoặc dữ liệu được chia sẻ không hấp dẫnMột lỗi phổ biến là chia sẻ dữ liệu giữa các quy trình không thể tuần tự hóa. Python có một quy trình tuần tự hóa đối tượng tích hợp được gọi là Pickle, trong đó các đối tượng được ngâm hoặc không bị ràng buộc khi tuần tự hóa và không bị hủy. Khi chia sẻ dữ liệu giữa các quy trình, dữ liệu sẽ tự động ngâm. Điều này bao gồm các đối số được truyền đến các chức năng tác vụ mục tiêu, dữ liệu được trả về từ các chức năng tác vụ mục tiêu và dữ liệu được truy cập trực tiếp, chẳng hạn như các biến toàn cầu. Nếu dữ liệu được chia sẻ giữa các quy trình không thể tự động ngâm, thì picklingError sẽ được nâng lên.PicklingError will be raised. Hầu hết các đối tượng Python bình thường có thể được ngâm. Ví dụ về các đối tượng không thể dưa chua là những đối tượng có thể có kết nối mở, chẳng hạn như tệp, cơ sở dữ liệu, máy chủ hoặc tương tự. Chúng ta có thể chứng minh điều này với một ví dụ bên dưới cố gắng vượt qua xử lý tệp như một đối số cho chức năng tác vụ đích.
Chạy ví dụ, chúng ta có thể thấy rằng nó rơi với một lỗi cho biết rằng đối số không thể được ngâm để truyền cho quy trình của công nhân.
Sửa lỗi này liên quan đến việc cập nhật chữ ký của chức năng gọi lại của bạn để bao gồm kết quả từ tác vụ. # chức năng gọi lại kết quả DEF Handler (kết quả):pickle module. & nbsp; & nbsp; & nbsp; & nbsp;Bạn có thể tìm hiểu thêm về việc sử dụng các chức năng gọi lại với các tác vụ không đồng bộ trong hướng dẫn:print() statement from target task functions. Đa xử lý các chức năng gọi lại hồ bơi trong Pythonprint() statement in Python does not flush output. Lỗi này cũng có thể xảy ra với cuộc gọi lại lỗi và quên thêm lỗi làm đối số trong hàm gọi lại lỗi.
Một lỗi phổ biến là chia sẻ dữ liệu giữa các quy trình không thể tuần tự hóa. Python có một quy trình tuần tự hóa đối tượng tích hợp được gọi là Pickle, trong đó các đối tượng được ngâm hoặc không bị ràng buộc khi tuần tự hóa và không bị hủy.print() function from spawned or forked processes because standard out will buffer output by default. Điều này có nghĩa là nếu bạn gọi print () từ các hàm tác vụ mục tiêu trong đa xử lý.pool, bạn có thể sẽ không thấy các câu lệnh in trên tiêu chuẩn cho đến khi các quy trình của công nhân bị đóng.print() from target task functions in the multiprocessing.pool, you probably will not see the print statements on standard out until the worker processes are closed. Điều này sẽ gây nhầm lẫn vì nó sẽ trông giống như chương trình của bạn không hoạt động chính xác, ví dụ: có lỗi. Ví dụ dưới đây thể hiện điều này với hàm tác vụ mục tiêu sẽ gọi Print () để báo cáo một số trạng thái.
Chạy ví dụ sẽ đợi cho đến khi tất cả các tác vụ trong nhóm quy trình đã hoàn thành trước khi in tất cả các tin nhắn trên tiêu chuẩn.
Điều này có thể được sửa bằng cách cập nhật tất cả các cuộc gọi lên câu lệnh in () được gọi từ các chức năng tác vụ mục tiêu để xóa đầu ra sau mỗi cuộc gọi.print() statement called from target task functions to flush output after each call. Điều này có thể đạt được bằng cách đặt đối số của Flush Flush thành True, ví dụ:flush” argument to True, for example:
Bạn có thể tìm hiểu thêm về in từ các quá trình trẻ em trong hướng dẫn:
Những câu hỏi phổ biến khi sử dụng nhóm đa xử lýPhần này trả lời các câu hỏi phổ biến của các nhà phát triển khi sử dụng đa xử lý.pool.multiprocessing.Pool. Bạn có câu hỏi về đa xử lý.pool? Đặt câu hỏi của bạn trong các bình luận bên dưới và tôi sẽ cố gắng hết sức để trả lời nó và có lẽ thêm nó vào danh sách các câu hỏi này. Làm thế nào để bạn ngừng chạy các nhiệm vụ một cách an toàn?Nhóm quy trình không cung cấp một cơ chế để ngăn chặn một cách an toàn tất cả các nhiệm vụ hiện đang chạy. Nó cung cấp một cách để chấm dứt mạnh mẽ tất cả các quy trình công nhân đang chạy thông qua hàm chấm dứt (). Cách tiếp cận này quá tích cực đối với hầu hết các trường hợp sử dụng vì điều đó có nghĩa là nhóm quy trình không còn có thể được sử dụng.terminate() function. This approach is too aggressive for most use cases as it will mean the process pool can no longer be used. Thay vào đó, chúng ta có thể phát triển một cơ chế để ngăn chặn tất cả các tác vụ chạy một cách an toàn trong một nhóm quy trình bằng cách sử dụng đối tượng đa xử lý.multiprocessing.Event object. Đầu tiên, một đối tượng sự kiện phải được tạo và chia sẻ giữa tất cả các tác vụ đang chạy.Event object must be created and shared among all running tasks. Ví dụ:
print (f'done: {value} ', flush = true) Bạn có thể tìm hiểu thêm về in từ các quá trình trẻ em trong hướng dẫn:is_set() function and made True via the set() function. Cách in () từ một quá trình trẻ em ở Pythonmultiprocessing.Event in the tutorial:
Phần này trả lời các câu hỏi phổ biến của các nhà phát triển khi sử dụng đa xử lý.pool.multiprocessing.Event object cannot be passed as an argument to task functions executed in the process pool. Bạn có câu hỏi về đa xử lý.pool? Đặt câu hỏi của bạn trong các bình luận bên dưới và tôi sẽ cố gắng hết sức để trả lời nó và có lẽ thêm nó vào danh sách các câu hỏi này.Event with tasks in the pool.
Nó cung cấp một cách để chấm dứt mạnh mẽ tất cả các quy trình công nhân đang chạy thông qua hàm chấm dứt (). Cách tiếp cận này quá tích cực đối với hầu hết các trường hợp sử dụng vì điều đó có nghĩa là nhóm quy trình không còn có thể được sử dụng. Thay vào đó, chúng ta có thể phát triển một cơ chế để ngăn chặn tất cả các tác vụ chạy một cách an toàn trong một nhóm quy trình bằng cách sử dụng đối tượng đa xử lý.multiprocessing.Manager creates a process and is responsible for managing a centralized version of an object. It then provides proxy objects that can be used in other processes that keep up-to-date with the single centralized object. Đầu tiên, một đối tượng sự kiện phải được tạo và chia sẻ giữa tất cả các tác vụ đang chạy.Manager is a useful way to centralize a synchronization primitive like an event shared among multiple worker processes. Ví dụ:multiprocessing.Manager using the context manager interface. Ví dụ:
Cách in () từ một quá trình trẻ em ở PythonEvent object using the manager. Những câu hỏi phổ biến khi sử dụng nhóm đa xử lýEvent object in the manager process that we can share among child worker processes directly or indirectly. Ví dụ:
print (f'done: {value} ', flush = true) Bạn có thể tìm hiểu thêm về in từ các quá trình trẻ em trong hướng dẫn:Event as an argument to the target task function. Ví dụ:
Hàm tùy chỉnh thực thi nhiệm vụ có thể kiểm tra trạng thái của đối tượng sự kiện theo định kỳ, chẳng hạn như mỗi lần lặp của một vòng lặp.Event object periodically, such as each iteration of a loop. Nếu đặt sự kiện, chức năng tác vụ đích sau đó có thể chọn dừng, đóng bất kỳ tài nguyên nào nếu cần thiết.Event set, the target task function can then choose to stop, closing any resources if necessary.
Nếu đặt sự kiện, chức năng tác vụ đích sau đó có thể chọn dừng, đóng bất kỳ tài nguyên nào nếu cần thiết. # chức năng được thực thi trong các quy trình công nhân
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; Chạy ví dụ đầu tiên tạo ra người quản lý, sau đó tạo đối tượng sự kiện được chia sẻ từ người quản lý. Nhóm quy trình sau đó được tạo bằng cấu hình mặc định. Các đối số cho các nhiệm vụ được chuẩn bị, sau đó bốn nhiệm vụ được ban hành không đồng bộ vào nhóm quy trình.AsyncResult for the issued tasks to stop. Quá trình chính sau đó chặn trong giây lát. Mỗi nhiệm vụ bắt đầu, báo cáo một tin nhắn sau đó bắt đầu vòng lặp chính của nó. Quá trình chính thức dậy và thiết lập sự kiện, yêu cầu tất cả các nhiệm vụ được ban hành dừng lại. Sau đó, nó chờ đợi sự không đồng bộ để các nhiệm vụ được ban hành dừng lại.
Bạn có thể tìm hiểu thêm về cách dừng tất cả các nhiệm vụ một cách an toàn trong nhóm đa xử lý trong hướng dẫn:
Làm thế nào để giết tất cả các nhiệm vụ?Giết sát nhiệm vụ trong nhóm quá trình là một cách tiếp cận tích cực. Nó có thể gây ra các tác dụng phụ không mong muốn. Ví dụ, việc tiêu diệt các tác vụ trong quá trình trong khi chúng đang chạy có thể có nghĩa là các tài nguyên như tệp, ổ cắm và cấu trúc dữ liệu được sử dụng bởi các tác vụ chạy không được đóng hoặc để ở trạng thái hữu ích. Một giải pháp thay thế để giết chết các nhiệm vụ mạnh mẽ có thể là tạm dừng một cách an toàn hoặc dừng một nhiệm vụ bằng cách sử dụng một nguyên thủy đồng bộ hóa như một đối tượng đa xử lý.multiprocessing.Event object. Đa xử lý.pool.pool không cung cấp một cơ chế để tiêu diệt tất cả các nhiệm vụ và tiếp tục sử dụng nhóm.multiprocessing.pool.Pool does not provide a mechanism to kill all tasks and continue using the pool. Tuy nhiên, nhóm quy trình cung cấp hàm chấm dứt () sẽ chấm dứt tất cả các quy trình nhân viên trẻ em ngay lập tức, lần lượt giết chết tất cả các nhiệm vụ.terminate() function which will forcefully terminate all child worker processes immediately, in turn killing all tasks. Ví dụ:
Điều này đạt được bằng cách gửi tín hiệu Sigkill cho mỗi quy trình nhân viên trẻ em trong nhóm quy trình. Tín hiệu này không thể được xử lý và ngay lập tức chấm dứt các quá trình con.SIGKILL signal to each child worker process in the process pool. This signal cannot be handled and immediately terminates the child processes. Bạn có thể tìm hiểu thêm về việc tắt nhóm quy trình trong hướng dẫn:
Nhóm quy trình có thể mất một chút thời gian để giết mạnh tất cả các quá trình trẻ em, do đó, đó là một thông lệ tốt để gọi hàm tham gia () sau khi gọi chấm dứt (). Hàm tham gia () sẽ chỉ quay lại sau khi tất cả các quy trình nhân viên trẻ em được đóng hoàn toàn.join() function after calling terminate(). The join() function will only return after all child worker processes are completely closed. Ví dụ:
Bạn có thể tìm hiểu thêm về việc tắt nhóm quy trình trong hướng dẫn: Cách tắt nhóm Quy trình trong Pythonapply_async(), map_async() and starmap_async() to issue tasks. Nhóm quy trình có thể mất một chút thời gian để giết mạnh tất cả các quá trình trẻ em, do đó, đó là một thông lệ tốt để gọi hàm tham gia () sau khi gọi chấm dứt (). Hàm tham gia () sẽ chỉ quay lại sau khi tất cả các quy trình nhân viên trẻ em được đóng hoàn toàn.terminate() function. # Đợi một chút thời gian để tất cả các quy trình công nhân dừng lại Việc giết các nhiệm vụ trong nhóm quy trình giả định rằng quy trình chính phát hành các nhiệm vụ cho nhóm quy trình là miễn phí và có thể tiêu diệt nhóm quy trình.
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; Chạy ví dụ đầu tiên tạo nhóm quy trình với cấu hình mặc định.SIGKILL signal to each child worker process causing them to terminate immediately. In turn the tasks that each child worker process is executing is forcefully terminated immediately. Quá trình chính sau đó chặn một phần nhỏ một giây cho đến khi các quy trình nhân viên trẻ em được dừng lại, sau đó tiếp tục, đóng ứng dụng.
Bạn có thể tìm hiểu thêm về việc giết tất cả các nhiệm vụ trong nhóm quy trình trong hướng dẫn:
Làm thế nào để bạn chờ đợi tất cả các nhiệm vụ hoàn thành?Dưới đây là hai cách mà chúng ta có thể chờ đợi các nhiệm vụ hoàn thành trong đa xử lý.pool.pool.multiprocessing.pool.Pool. Họ đang:
Hãy cùng xem xét kỹ hơn về từng cách tiếp cận. Nhiệm vụ có thể được ban hành không đồng bộ vào nhóm quy trình. Điều này có thể đạt được bằng cách sử dụng một hàm như application_async (), map_async () và starmap_async (). Các chức năng này trả về một đối tượng không đồng bộ.apply_async(), map_async(), and starmap_async(). These functions return an AsyncResult object. Chúng ta có thể chờ một loạt các tác vụ được phát hành không đồng bộ vào nhóm quy trình để hoàn thành bằng cách gọi hàm Wait () trên đối tượng Asyncresult được trả về.wait() function on the returned AsyncResult object. Ví dụ:
Nếu nhiều loạt các tác vụ không đồng bộ được cấp cho nhóm quy trình, chúng ta có thể thu thập các đối tượng không đồng bộ được trả lại và chờ lần lượt chờ đợi.AsyncResult objects that are returned and wait on each in turn. Chúng tôi có thể phát hành nhiều lô các nhiệm vụ không đồng bộ vào nhóm quy trình và không bị treo vào các đối tượng không đồng bộ được trả về.AsyncResult objects that are returned. Thay vào đó, chúng tôi có thể chờ tất cả các nhiệm vụ trong nhóm quy trình hoàn thành bằng cách lần đầu tiên tắt nhóm quy trình, sau đó tham gia để chờ tất cả các nhiệm vụ được phát hành được hoàn thành. Điều này có thể đạt được bằng cách gọi đầu tiên chức năng đóng () sẽ ngăn chặn bất kỳ nhiệm vụ nào được cấp thêm cho nhóm quy trình và đóng các quy trình của công nhân sau khi tất cả các nhiệm vụ hoàn tất.close() function that will prevent any further tasks to be issued to the process pool and close down the worker processes once all tasks are complete. Sau đó chúng ta có thể gọi hàm Jopnow (). Điều này sẽ chặn người gọi cho đến khi tất cả các tác vụ trong nhóm quy trình được hoàn thành và các quy trình con của người lao động trong nhóm quy trình đã đóng.join() function. This will block the caller until all tasks in the process pools are completed and the worker child processes in the process pool have closed. Ví dụ:
Nếu nhiều loạt các tác vụ không đồng bộ được cấp cho nhóm quy trình, chúng ta có thể thu thập các đối tượng không đồng bộ được trả lại và chờ lần lượt chờ đợi. Chúng tôi có thể phát hành nhiều lô các nhiệm vụ không đồng bộ vào nhóm quy trình và không bị treo vào các đối tượng không đồng bộ được trả về. Thay vào đó, chúng tôi có thể chờ tất cả các nhiệm vụ trong nhóm quy trình hoàn thành bằng cách lần đầu tiên tắt nhóm quy trình, sau đó tham gia để chờ tất cả các nhiệm vụ được phát hành được hoàn thành.AsyncResult object. Điều này có thể đạt được bằng cách gọi đầu tiên chức năng đóng () sẽ ngăn chặn bất kỳ nhiệm vụ nào được cấp thêm cho nhóm quy trình và đóng các quy trình của công nhân sau khi tất cả các nhiệm vụ hoàn tất.
& nbsp; & nbsp; & nbsp; & nbsp;# tạo và định cấu hình nhóm quy trình & nbsp; & nbsp; & nbsp; & nbsp; với pool () aspool:AsyncResult object is returned and the main process then blocks until the issued tasks are completed. & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# vấn đề & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;wait() function returns and the main process continues on. & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# Báo cáo tất cả
Nhiệm vụ 4 thực hiện
Làm thế nào để bạn có được kết quả đầu tiên?Có hai cách tiếp cận chính mà chúng ta có thể sử dụng để có được kết quả từ nhiệm vụ đầu tiên để hoàn thành trong nhóm quy trình. Họ đang:
Hãy cùng nhau xem xét kỹ hơn từng cách tiếp cận. Một đa xử lý.queue có thể được tạo và chia sẻ giữa tất cả các nhiệm vụ được cấp cho nhóm quy trình.multiprocessing.Queue can be created and shared among all tasks issued to the process pool. Khi các nhiệm vụ kết thúc, họ có thể đưa kết quả của họ lên hàng đợi. Quá trình cha mẹ chờ kết quả đầu tiên có thể nhận kết quả đầu tiên có sẵn thông qua hàng đợi được chia sẻ. Một hàng đợi đa xử lý có thể được tạo ra theo bình thường. Ví dụ:
Chúng tôi không thể chia sẻ hàng đợi trực tiếp với mỗi nhiệm vụ vào nhóm quy trình vì nó sẽ dẫn đến lỗi. Thay vào đó, chúng tôi có thể chia sẻ hàng đợi với chức năng khởi tạo cho từng quy trình nhân viên trẻ em. Hàng đợi có thể được lưu trữ trong một biến toàn cầu và được cung cấp cho tất cả các nhiệm vụ được thực hiện bởi tất cả các công nhân. Điều này yêu cầu chúng tôi xác định chức năng khởi tạo nhân viên trẻ em lấy hàng đợi làm đối số, tuyên bố một biến toàn cầu có sẵn cho tất cả các nhiệm vụ được thực hiện bởi người lao động, sau đó lưu trữ hàng đợi trong biến toàn cầu. Ví dụ:
Điều này yêu cầu chúng tôi xác định chức năng khởi tạo nhân viên trẻ em lấy hàng đợi làm đối số, tuyên bố một biến toàn cầu có sẵn cho tất cả các nhiệm vụ được thực hiện bởi người lao động, sau đó lưu trữ hàng đợi trong biến toàn cầu.
Chúng tôi không thể chia sẻ hàng đợi trực tiếp với mỗi nhiệm vụ vào nhóm quy trình vì nó sẽ dẫn đến lỗi.
Điều này yêu cầu chúng tôi xác định chức năng khởi tạo nhân viên trẻ em lấy hàng đợi làm đối số, tuyên bố một biến toàn cầu có sẵn cho tất cả các nhiệm vụ được thực hiện bởi người lao động, sau đó lưu trữ hàng đợi trong biến toàn cầu.put() function and passing the result object. Ví dụ:
Chúng tôi không thể chia sẻ hàng đợi trực tiếp với mỗi nhiệm vụ vào nhóm quy trình vì nó sẽ dẫn đến lỗi.get() function on the queue. This call will block until a result is available. Ví dụ:
Chúng tôi không thể chia sẻ hàng đợi trực tiếp với mỗi nhiệm vụ vào nhóm quy trình vì nó sẽ dẫn đến lỗi.
Điều này yêu cầu chúng tôi xác định chức năng khởi tạo nhân viên trẻ em lấy hàng đợi làm đối số, tuyên bố một biến toàn cầu có sẵn cho tất cả các nhiệm vụ được thực hiện bởi người lao động, sau đó lưu trữ hàng đợi trong biến toàn cầu.imap_unordered(). # Khởi tạo quy trình công nhân def init_worker (arg_queue):imap_unordered() function. Ví dụ:
Chúng tôi không thể chia sẻ hàng đợi trực tiếp với mỗi nhiệm vụ vào nhóm quy trình vì nó sẽ dẫn đến lỗi.next() function on the returned iterable to get the result from the first task to complete in the process pool. Thay vào đó, chúng tôi có thể chia sẻ hàng đợi với chức năng khởi tạo cho từng quy trình nhân viên trẻ em. Hàng đợi có thể được lưu trữ trong một biến toàn cầu và được cung cấp cho tất cả các nhiệm vụ được thực hiện bởi tất cả các công nhân.next() function returns the next item in an iterable. Ví dụ:
Chúng tôi không thể chia sẻ hàng đợi trực tiếp với mỗi nhiệm vụ vào nhóm quy trình vì nó sẽ dẫn đến lỗi.imap_unordered() function in the tutorial:
Điều này yêu cầu chúng tôi xác định chức năng khởi tạo nhân viên trẻ em lấy hàng đợi làm đối số, tuyên bố một biến toàn cầu có sẵn cho tất cả các nhiệm vụ được thực hiện bởi người lao động, sau đó lưu trữ hàng đợi trong biến toàn cầu.imap_unordered() function and get the first result. # Khởi tạo quy trình công nhânimap_unordered() function. This will return an iterable that will yield results in the order that the tasks have completed. We can then get the first value from the iterable in order to get the first result. def init_worker (arg_queue):
Chạy ví dụ đầu tiên tạo ra nhóm quy trình. Sau đó, nó phát hành tất cả các nhiệm vụ cho nhóm quy trình và trả về một kết quả có thể điều chỉnh được. Quá trình chính sau đó chặn, chờ kết quả đầu tiên được cung cấp. Một tập hợp con của các nhiệm vụ bắt đầu thực thi. Mỗi tác vụ tạo ra một số ngẫu nhiên, báo cáo giá trị, khối, sau đó trả về một tuple của giá trị số nguyên và số ngẫu nhiên được tạo. Một kết quả được nhận bởi quy trình chính và được báo cáo. Nhóm quy trình và tất cả các nhiệm vụ còn lại sau đó bị chấm dứt mạnh mẽ. Điều này nhấn mạnh một cách đơn giản để có được kết quả đầu tiên từ nhiều nhiệm vụ trong nhóm quy trình. Lưu ý, kết quả sẽ khác nhau mỗi khi chương trình được chạy do sử dụng các số ngẫu nhiên.
Bạn có thể tìm hiểu thêm về cách chờ đợi nhiệm vụ đầu tiên hoàn thành trong hướng dẫn:
Làm thế nào để bạn tự động thay đổi số lượng quy trìnhBạn không thể tự động tăng hoặc giảm số lượng các quy trình trong một đa xử lý.pool.multiprocessing.Pool. Số lượng các quy trình được cố định khi đa xử lý.pool được cấu hình trong lệnh gọi đến hàm tạo đối tượng.multiprocessing.Pool is configured in the call to the object constructor. Ví dụ:
Làm thế nào để bạn các nhiệm vụ đơn vị và xử lý nhóm?Bạn có thể trực tiếp kiểm tra các chức năng tác vụ mục tiêu của mình, có thể chế giễu mọi tài nguyên bên ngoài cần thiết. Bạn có thể kiểm tra đơn vị sử dụng nhóm quy trình với các tác vụ giả không tương tác với các tài nguyên bên ngoài. Kiểm tra đơn vị các tác vụ và bản thân nhóm quy trình phải được coi là một phần của thiết kế của bạn và có thể yêu cầu kết nối đó với tài nguyên IO có thể định cấu hình để nó có thể bị chế giễu và chức năng tác vụ đích được gọi là nhóm quy trình của bạn có thể định cấu hình để có thể định cấu hình Nó có thể bị chế giễu. Làm thế nào để bạn so sánh hiệu suất nối tiếp với hiệu suất song song?Bạn có thể so sánh hiệu suất của chương trình của bạn có và không có nhóm quy trình. Đây có thể là một bài tập hữu ích để xác nhận rằng việc sử dụng đa xử lý.pool trong chương trình của bạn đã dẫn đến tăng tốc.multiprocessing.Pool in your program has resulted in a speed-up. Có lẽ cách tiếp cận đơn giản nhất là ghi lại thủ công thời gian bắt đầu và kết thúc của mã của bạn và trừ kết thúc từ thời gian bắt đầu để báo cáo tổng thời gian thực hiện. Sau đó ghi lại thời gian có và không có việc sử dụng nhóm quy trình.
Sử dụng thời gian thực hiện chương trình trung bình có thể cung cấp thời gian chương trình ổn định hơn so với chạy một lần. Bạn có thể ghi lại thời gian thực hiện 3 lần trở lên cho chương trình của mình mà không cần nhóm quy trình sau đó tính trung bình khi tổng thời gian chia cho tổng số lần chạy. Sau đó lặp lại bài tập này để tính thời gian trung bình với nhóm quy trình. Điều này có thể chỉ phù hợp nếu thời gian chạy của chương trình của bạn là vài phút thay vì hàng giờ. Sau đó, bạn có thể so sánh phiên bản nối tiếp so với song song bằng cách tính toán tốc độ tăng lên nhiều như:
Ví dụ: nếu lần chạy nối tiếp của một chương trình mất 15 phút (900 giây) và phiên bản song song với đa xử lý.pool mất 5 phút (300 giây), thì tỷ lệ phần trăm sẽ được tính như:multiprocessing.Pool took 5 minutes (300 seconds), then the percentage multiple up would be calculated as:
Tăng tốc nhiều = 3multiprocessing.Pool is 3 times faster or 3x faster. Đó là, phiên bản song song của chương trình với đa xử lý.pool nhanh hơn gấp 3 lần hoặc nhanh hơn gấp 3 lần.
Trong ví dụ này, phiên bản song song nhanh hơn 300% so với phiên bản nối tiếp. Làm thế nào để bạn đặt Chunksize trong bản đồ ()?Hàm bản đồ () và các hàm liên quan như starmap () và imap () trên đa xử lý.pool có một tham số có tên là Chunksize.map() function, and related functions like starmap() and imap() on the multiprocessing.Pool takes a parameter called “chunksize“. Đối số của người Viking, đối số của người Viking kiểm soát việc ánh xạ các mục trong điều đó được chuyển sang bản đồ () cho các tác vụ được sử dụng trong đa xử lý.pool.chunksize” argument controls the mapping of items in the iterable passed to map() to tasks used in the multiprocessing.Pool. Ví dụ:
Giá trị của một có nghĩa là một mục được ánh xạ tới một tác vụ. Hãy nhớ lại rằng dữ liệu cho từng tác vụ theo các đối số được gửi đến hàm tác vụ mục tiêu và các giá trị được trả về phải được tuần tự hóa bằng Pickle. Điều này xảy ra tự động, nhưng phải chịu một số chi phí tính toán và bộ nhớ, thêm chi phí cho mỗi nhiệm vụ được xử lý bởi nhóm đa xử lý. Khi có một số lượng lớn các tác vụ hoặc nhiệm vụ tương đối nhanh chóng để tính toán, thì nên điều chỉnh các mục tiêu để tối đa hóa việc nhóm các mục để xử lý các tác vụ nhóm để giảm thiểu chi phí cho mỗi nhiệm vụ và lần lượt giảm thời gian tính toán tổng thể. Theo mặc định, chunksize được đặt thành không có. Trong trường hợp này, phần Chunksize sẽ không được đặt thành 1 như chúng ta có thể mong đợi, thay vào đó, một đoạn được tính toán được tính toán tự động.chunksize is set to None. In this case, the chunksize will not be set to 1 as we might expect, instead, a chunksize is calculated automatically. Chúng ta có thể thấy điều này trong mã nguồn cho lớp nhóm:Pool class:
forresult inpool.map (nhiệm vụ, vật phẩm, chunksize = 1)divmod() will return the result (quotient) and remainder. & nbsp; & nbsp; & nbsp; & nbsp;# ... Giá trị của một có nghĩa là một mục được ánh xạ tới một tác vụ.
Chúng ta có thể thấy điều này trong mã nguồn cho lớp nhóm: ifchunksize isnone: DivMod () sẽ trả về kết quả (thương số) và phần còn lại. Ở đây, chúng tôi đang chia độ dài của đầu vào 4 lần số lượng công nhân trong nhóm.
Chunksize, thêm = 62500, 0: the (len(items) / number_of_workers) division may need to be rounded as the “chunksize” argument must be a positive integer. Ví dụ:
Giá trị của một có nghĩa là một mục được ánh xạ tới một tác vụ. Hãy nhớ lại rằng dữ liệu cho từng tác vụ theo các đối số được gửi đến hàm tác vụ mục tiêu và các giá trị được trả về phải được tuần tự hóa bằng Pickle. Điều này xảy ra tự động, nhưng phải chịu một số chi phí tính toán và bộ nhớ, thêm chi phí cho mỗi nhiệm vụ được xử lý bởi nhóm đa xử lý.Khi có một số lượng lớn các tác vụ hoặc nhiệm vụ tương đối nhanh chóng để tính toán, thì nên điều chỉnh các mục tiêu để tối đa hóa việc nhóm các mục để xử lý các tác vụ nhóm để giảm thiểu chi phí cho mỗi nhiệm vụ và lần lượt giảm thời gian tính toán tổng thể. Theo mặc định, chunksize được đặt thành không có. Trong trường hợp này, phần Chunksize sẽ không được đặt thành 1 như chúng ta có thể mong đợi, thay vào đó, một đoạn được tính toán được tính toán tự động.
DivMod () sẽ trả về kết quả (thương số) và phần còn lại. Ở đây, chúng tôi đang chia độ dài của đầu vào 4 lần số lượng công nhân trong nhóm. Nếu chúng tôi có 4 quy trình công nhân và một danh sách các mục với 1.000.000 yếu tố, thì phần mềm mặc định sẽ được tính như sau: Chunksize, Extra = Divmod (1.000.000, 4 * 4) Chunksize, Extra = Divmod (1.000.000, 16)apply_async() function that returns a ResultAsync.
forresult inpool.map (nhiệm vụ, vật phẩm, chunksize = 1) Ví dụ:
& nbsp; & nbsp; & nbsp; & nbsp;# ... Giá trị của một có nghĩa là một mục được ánh xạ tới một tác vụ. Hãy nhớ lại rằng dữ liệu cho từng tác vụ theo các đối số được gửi đến hàm tác vụ mục tiêu và các giá trị được trả về phải được tuần tự hóa bằng Pickle. Điều này xảy ra tự động, nhưng phải chịu một số chi phí tính toán và bộ nhớ, thêm chi phí cho mỗi nhiệm vụ được xử lý bởi nhóm đa xử lý. Khi có một số lượng lớn các tác vụ hoặc nhiệm vụ tương đối nhanh chóng để tính toán, thì nên điều chỉnh các mục tiêu để tối đa hóa việc nhóm các mục để xử lý các tác vụ nhóm để giảm thiểu chi phí cho mỗi nhiệm vụ và lần lượt giảm thời gian tính toán tổng thể. Theo mặc định, chunksize được đặt thành không có. Trong trường hợp này, phần Chunksize sẽ không được đặt thành 1 như chúng ta có thể mong đợi, thay vào đó, một đoạn được tính toán được tính toán tự động. Như vậy, chúng tôi có thể trực tiếp phát hành các tác vụ tiếp theo từ chức năng gọi lại. Ví dụ:
Hàm gọi lại có thể được chỉ định khi ban hành các tác vụ trong quy trình chính thông qua đối số gọi lại của Cameron.callback” argument. Ví dụ:
& nbsp; & nbsp; & nbsp; & nbsp;# Kiểm tra kết quả của một nhiệm vụ đã phát hành & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; Hàm gọi lại có thể được chỉ định khi ban hành các tác vụ trong quy trình chính thông qua đối số gọi lại của Cameron.
& nbsp; & nbsp; & nbsp; & nbsp; với pool () aspool: & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & NBSP;task1() are issued as tasks to the process pool and an AsyncResult is returned. The main process then blocks waiting for all first-round tasks to complete. & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# tất cả đã hoàn thành & nbsp; & nbsp; & nbsp; & nbsp; in ('tất cả đã hoàn thành.') Chạy ví dụ đầu tiên tạo và bắt đầu nhóm quy trình với cấu hình mặc định. Điều này nhấn mạnh cách chúng ta có thể tự động phát hành các nhiệm vụ tiếp theo cho nhóm quy trình từ quy trình chính.
Bạn có thể tìm hiểu thêm về cách phát hành một nhiệm vụ tiếp theo trong hướng dẫn:
Làm thế nào để bạn thể hiện sự tiến bộ của tất cả các nhiệm vụ?Chúng ta có thể hiển thị tiến trình của các tác vụ trong nhóm quy trình bằng cách sử dụng chức năng gọi lại. Điều này có thể đạt được bằng cách ban hành các tác vụ không đồng bộ vào nhóm quy trình, chẳng hạn như thông qua hàm application_async () và chỉ định chức năng gọi lại thông qua đối số gọi lại của Cameron.apply_async() function and specifying a callback function via the “callback” argument. Ví dụ:
Hàm gọi lại tùy chỉnh của chúng tôi sau đó sẽ được gọi sau mỗi nhiệm vụ trong nhóm quy trình được hoàn thành. Sau đó, chúng ta có thể thực hiện một số hành động để hiển thị tiến trình của các tác vụ đã hoàn thành trong hàm gọi lại, chẳng hạn như in dấu chấm ra tiêu chuẩn. Ví dụ:
Hàm gọi lại tùy chỉnh của chúng tôi sau đó sẽ được gọi sau mỗi nhiệm vụ trong nhóm quy trình được hoàn thành. Sau đó, chúng ta có thể thực hiện một số hành động để hiển thị tiến trình của các tác vụ đã hoàn thành trong hàm gọi lại, chẳng hạn như in dấu chấm ra tiêu chuẩn. # Chỉ báo tiến trình cho các tác vụ trong nhóm quy trình
# Nhiệm vụ được thực hiện trong một quy trình công nhân nhiệm vụ def (): & nbsp; & nbsp; & nbsp; & nbsp;# tạo một giá trị ngẫu nhiên & nbsp; & nbsp; & nbsp; & nbsp;# block trong giây lát # Bảo vệ điểm vào & nbsp; & nbsp; & nbsp; & nbsp;# tạo và định cấu hình nhóm quy trình & nbsp; & nbsp; & nbsp; & nbsp; với pool () aspool:
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;
& nbsp; & nbsp; & nbsp; & nbsp;# báo cáo tất cả đã hoàn thành& nbsp; & nbsp; & nbsp; & nbsp; in ('\ ndone!')) Chạy ví dụ đầu tiên tạo ra nhóm quy trình.RuntimeError when starting a new Process in Python. Sau đó, 20 nhiệm vụ được phát hành cho nhóm, mỗi lần một.
Điều này sẽ xảy ra trên Windows và MacOS trong đó phương thức bắt đầu mặc định là ‘Spawn. Nó cũng có thể xảy ra khi bạn định cấu hình chương trình của mình để sử dụng phương thức bắt đầu ‘Spawn‘ trên các nền tảng khác.spawn‘. It may also happen when you configure your program to use the ‘spawn‘ start method on other platforms. Bạn sẽ nhận được thời gian chạy này khi sử dụng Multiprocessing.pool và không bảo vệ điểm nhập khi sử dụng phương thức bắt đầu ‘Spawn.RuntimeError when using the multiprocessing.Pool and do not protect the entry point when using the ‘spawn’ start method. Việc sửa chữa liên quan đến việc kiểm tra xem mã có chạy trong môi trường cấp cao nhất và chỉ sau đó, hãy cố gắng bắt đầu một quy trình mới. Đây là một thực hành tốt nhất. Thành ngữ cho bản sửa lỗi này, như đã nêu trong thông báo của RunTimeError, là sử dụng một câu chuyện if và kiểm tra xem tên của mô-đun bằng với chuỗi ‘__main__.RuntimeError, is to use an if-statement and check if the name of the module is equal to the string ‘__main__‘. Ví dụ:
Đây được gọi là bảo vệ điểm vào điểm vào của chương trình. Nhớ lại, __name__ là một biến đề cập đến tên của mô -đun thực thi mã hiện tại.__name__ is a variable that refers to the name of the module executing the current code. Ngoài ra, hãy nhớ lại rằng ‘__main__ là tên của môi trường cấp cao nhất được sử dụng để thực hiện chương trình Python.__main__‘ is the name of the top-level environment used to execute a Python program. Sử dụng một câu chuyện IF để kiểm tra xem mô-đun có phải là môi trường cấp cao nhất không và chỉ bắt đầu các quy trình con trong khối đó sẽ giải quyết thời gian chạy.RuntimeError. Điều đó có nghĩa là nếu tệp python được nhập, thì mã được bảo vệ bởi if-satatement sẽ không chạy. Nó sẽ chỉ chạy khi tệp Python được chạy trực tiếp, ví dụ: là môi trường cấp cao nhất. Thành ngữ if-statement là bắt buộc, ngay cả khi điểm nhập của chương trình gọi một hàm tự bắt đầu quy trình con. Bạn có thể tìm hiểu thêm về việc bảo vệ điểm nhập khi sử dụng đa xử lý trong hướng dẫn:
Tôi có cần gọi Freeze_support () không?Các chương trình Python có thể được chuyển đổi thành một Windows có thể thực thi. Trong quá trình chuyển đổi, các chương trình Python bị đóng băng. Nếu các chương trình này cố gắng bắt đầu các quy trình mới, nó sẽ dẫn đến RuntimEError. Do đó, nếu bạn có ý định đóng băng chương trình của bạn (ví dụ: chuyển đổi nó thành một windows có thể thực thi), bạn phải thêm hỗ trợ Freeze. Điều này có thể đạt được bằng cách gọi hàm freeze_support () là dòng đầu tiên của chương trình của bạn, như là dòng đầu tiên sau khi kiểm tra điểm nhập được bảo vệ; Ví dụ:freeze_support() function as the first line of your program, such the first line after checking for the protected entry point; for example:
Đây được gọi là bảo vệ điểm vào điểm vào của chương trình.
Ngoài ra, hãy nhớ lại rằng ‘__main__ là tên của môi trường cấp cao nhất được sử dụng để thực hiện chương trình Python.Sử dụng một câu chuyện IF để kiểm tra xem mô-đun có phải là môi trường cấp cao nhất không và chỉ bắt đầu các quy trình con trong khối đó sẽ giải quyết thời gian chạy. Điều đó có nghĩa là nếu tệp python được nhập, thì mã được bảo vệ bởi if-satatement sẽ không chạy. Nó sẽ chỉ chạy khi tệp Python được chạy trực tiếp, ví dụ: là môi trường cấp cao nhất.map(), starmap(), imap(), imap_unordered(), or apply() it does create an AsyncResult object for each task. Thành ngữ if-statement là bắt buộc, ngay cả khi điểm nhập của chương trình gọi một hàm tự bắt đầu quy trình con.AsyncResult when issuing tasks to the process pool using the functions:
Bạn có thể tìm hiểu thêm về việc bảo vệ điểm nhập khi sử dụng đa xử lý trong hướng dẫn:Thêm nếu __name__ == ‘__main__, khi sinh sản một quá trình conmultiprocessing.pool.Pool cannot be shared with child processes directly. Tôi có cần gọi Freeze_support () không? Các chương trình Python có thể được chuyển đổi thành một Windows có thể thực thi.NotImplementedError:
Do đó, nếu bạn có ý định đóng băng chương trình của bạn (ví dụ: chuyển đổi nó thành một windows có thể thực thi), bạn phải thêm hỗ trợ Freeze. Điều này có thể đạt được bằng cách gọi hàm freeze_support () là dòng đầu tiên của chương trình của bạn, như là dòng đầu tiên sau khi kiểm tra điểm nhập được bảo vệ; Ví dụ: # Điểm vào được bảo vệ Ví dụ:
Đây được gọi là bảo vệ điểm vào điểm vào của chương trình. Nhớ lại, __name__ là một biến đề cập đến tên của mô -đun thực thi mã hiện tại.
Thành ngữ if-statement là bắt buộc, ngay cả khi điểm nhập của chương trình gọi một hàm tự bắt đầu quy trình con. Bạn có thể tìm hiểu thêm về việc bảo vệ điểm nhập khi sử dụng đa xử lý trong hướng dẫn: Thêm nếu __name__ == ‘__main__, khi sinh sản một quá trình conmultiprocessing.Manager provides a way to create a centralized version of a Python object hosted on a server process. Tôi có cần gọi Freeze_support () không? Các chương trình Python có thể được chuyển đổi thành một Windows có thể thực thi. Trong quá trình chuyển đổi, các chương trình Python bị đóng băng. Nếu các chương trình này cố gắng bắt đầu các quy trình mới, nó sẽ dẫn đến RuntimEError.multiprocessing.Manager is a useful way to centralize a synchronization primitive like a multiprocessing.pool.Pool shared among multiple processes, such as worker processes in the pool itself. Trước tiên chúng ta có thể tạo một đa xử lý. Người quản lý bằng giao diện Trình quản lý ngữ cảnh.multiprocessing.Manager using the context manager interface. Ví dụ:
Sau đó, chúng ta có thể tạo một đối tượng đa xử lý được chia sẻ.pool.pool bằng cách sử dụng trình quản lý.multiprocessing.pool.Pool object using the manager. Điều này sẽ trả về một đối tượng proxy cho đối tượng đa xử lý.pool.pool trong quy trình trình quản lý mà chúng ta có thể chia sẻ giữa các quy trình nhân viên trẻ em hoặc gián tiếp.multiprocessing.pool.Pool object in the manager process that we can share among child worker processes directly or indirectly. Ví dụ:
với người quản lý () asmanager:multiprocessing.pool.Pool can then be passed to a child worker initialization function or to a task function as an argument to be executed by worker processes. & nbsp; & nbsp; & nbsp; & nbsp;# ... Sau đó, chúng ta có thể tạo một đối tượng đa xử lý được chia sẻ.pool.pool bằng cách sử dụng trình quản lý. Điều này sẽ trả về một đối tượng proxy cho đối tượng đa xử lý.pool.pool trong quy trình trình quản lý mà chúng ta có thể chia sẻ giữa các quy trình nhân viên trẻ em hoặc gián tiếp.
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; Chạy ví dụ đầu tiên tạo ra nhóm quy trình. Sau đó, nó phát hành nhiệm vụ không đồng bộ. Quá trình chính sau đó đóng nhóm quy trình và chờ tất cả các nhiệm vụ được cấp hoàn thành.
Trong trường hợp này, nhóm được truy cập thông qua đối tượng proxy mà không gặp vấn đề gì và các chi tiết của nhóm được báo cáo. Nó được đóng lại và được tạo ra với 8 quy trình lao động trẻ em.Lưu ý, cấu hình mặc định cụ thể của nhóm quy trình trên hệ thống của bạn có thể khác nhau. Nhiệm vụ hoàn thành và quy trình chính được thực hiện, đầu tiên chấm dứt nhóm quy trình, sau đó chấm dứt người quản lý. Điều này nhấn mạnh cách chúng tôi có thể chia sẻ một nhóm quy trình với các quy trình nhân viên trẻ em một cách gián tiếp bằng cách sử dụng người quản lý.Lock and RLock, as well as Semaphore, Barrier, Event, and Condition. Chi tiết hồ bơi: Làm thế nào để bạn sử dụng các nguyên thủy đồng bộ hóa (khóa, semaphore, v.v.) ở công nhân?multiprocessing.Lock. Các nguyên thủy đồng bộ hóa không thể được chia sẻ trực tiếp với công nhân trong nhóm quy trình.multiprocessing.Lock instance with worker processes indirectly, they are:
Các cách giải quyết tương tự sẽ hoạt động với tất cả các nguyên thủy đồng bộ hóa, nhưng chúng ta có thể chứng minh nó với đa xử lý.lock.fork‘ start method will work, and provides an easy way to share a lock with child worker processes. Có lẽ có ba cách chúng ta có thể chia sẻ một phiên bản đa bộ xử lý với các quy trình của công nhân một cách gián tiếp, chúng là:fork‘ start method is not available on all platforms, e.g. it cannot be used on Windows. Thay phiên, nếu chúng ta ngây thơ vượt qua một bộ xử lý.multiprocessing.Lock as an argument when initializing the process pool or in a task executed by the process pool, it will fail with an error, such as:
Thay vào đó, chúng ta phải sử dụng một đa xử lý.multiprocessing.Manager. Một đa xử lý. Người quản lý tạo ra một quy trình và chịu trách nhiệm quản lý một phiên bản tập trung của một đối tượng. Sau đó, nó cung cấp các đối tượng proxy có thể được sử dụng trong các quy trình khác luôn cập nhật với đối tượng tập trung duy nhất.multiprocessing.Manager creates a process and is responsible for managing a centralized version of an object. It then provides proxy objects that can be used in other processes that keep up-to-date with the single centralized object. Như vậy, sử dụng đa xử lý. Người quản lý là một cách hữu ích để tập trung một nguyên thủy đồng bộ hóa như đa xử lý.lock được chia sẻ giữa nhiều quy trình của công nhân.multiprocessing.Manager is a useful way to centralize a synchronization primitive like a multiprocessing.Lock shared among multiple worker processes. Trước tiên chúng ta có thể tạo một đa xử lý. Người quản lý bằng giao diện Trình quản lý ngữ cảnh.multiprocessing.Manager using the context manager interface. Ví dụ:
Sau đó, chúng ta có thể tạo một đối tượng đa xử lý được chia sẻ bằng cách sử dụng trình quản lý.multiprocessing.Lock object using the manager. Điều này sẽ trả về một đối tượng proxy cho đối tượng đa xử lý.multiprocessing.Lock object in the manager process that we can share among child worker processes directly or indirectly. Ví dụ:
với người quản lý () asmanager:multiprocessing.Lock can then be passed to a child worker initialization function or to a task function executed by worker processes. & nbsp; & nbsp; & nbsp; & nbsp;# ... Sau đó, chúng ta có thể tạo một đối tượng đa xử lý được chia sẻ bằng cách sử dụng trình quản lý.
Sử dụng khóa trong nhóm đa xử lýSử dụng semaphore trong nhóm đa xử lýmultiprocessing.Pool may not be the best solution for all concurrency problems in your program. Sử dụng một sự kiện trong nhóm đa xử lý Sử dụng một biến điều kiện trong nhóm đa xử lý Sử dụng một rào cản trong nhóm quy trình Phản đối phổ biến đối với việc sử dụng nhóm đa xử lýĐa xử lý.pool có thể không phải là giải pháp tốt nhất cho tất cả các vấn đề đồng thời trong chương trình của bạn.multiprocessing.Pool class. Điều đó đang được nói, cũng có thể có một số hiểu lầm đang ngăn bạn sử dụng đầy đủ và tốt nhất các khả năng của nhóm đa xử lý trong chương trình của bạn. Trong phần này, chúng tôi xem xét một số phản đối phổ biến mà các nhà phát triển thấy khi xem xét sử dụng nhóm đa xử lý trong mã của họ Hãy để lặn trong. Điều gì về khóa phiên dịch toàn cầu (GIL)? GIL thường không liên quan khi sử dụng các quy trình như lớp quy trình hoặc lớp đa xử lý.pool. Khóa thông dịch viên toàn cầu, hoặc ngắn hoàn toàn là Gil, là một quyết định thiết kế với trình thông dịch Python tham chiếu.threading.Thread class and the multiprocessing.pool.ThreadPool. It is not a consideration when using the multiprocessing Pool (unless you use additional threads within each task). Nó đề cập đến thực tế là việc triển khai trình thông dịch Python sử dụng khóa chính để ngăn chặn nhiều hơn một hướng dẫn Python thực thi cùng một lúc.
Việc thực hiện GIL có nghĩa là các luồng python có thể đồng thời, nhưng không thể chạy song song. Nhớ lại rằng đồng thời có nghĩa là có nhiều nhiệm vụ có thể được tiến hành cùng một lúc, song song có nghĩa là nhiều hơn một nhiệm vụ thực sự thực hiện cùng một lúc. Các nhiệm vụ song song là đồng thời ;, các nhiệm vụ đồng thời có thể hoặc không thể thực hiện song song.Yes. Đó là lý do đằng sau heuristic mà các chủ đề Python chỉ nên được sử dụng cho các nhiệm vụ ràng buộc IO, chứ không phải các nhiệm vụ liên kết CPU, vì các nhiệm vụ ràng buộc IO sẽ chờ trong hạt nhân hệ điều hành để các tài nguyên từ xa phản hồi (không thực hiện các hướng dẫn Python) , cho phép các chủ đề Python khác chạy và thực hiện các hướng dẫn Python. Như vậy, GIL là một sự cân nhắc khi sử dụng các luồng trong python, chẳng hạn như lớp chủ đề. Nó không phải là một sự cân nhắc khi sử dụng nhóm đa xử lý (trừ khi bạn sử dụng các luồng bổ sung trong mỗi nhiệm vụ).No. Bạn có thể tìm hiểu thêm về Pool so với Gil trong hướng dẫn: Nhóm đa xử lý và khóa phiên dịch toàn cầu (GIL) Có phải các quá trình Python có phải là các quy trình thực sự không?Python sử dụng các quy trình cấp hệ thống thực, còn được gọi là quy trình sinh sản hoặc quy trình forking, khả năng được cung cấp bởi các hệ điều hành hiện đại như Windows, Linux và MacOS. Aren lồng Python Processes Buggy? Nếu bạn đang sử dụng Python và sau đó bạn cần đồng thời, thì bạn làm việc với những gì bạn có. Câu hỏi là moot. Nếu bạn cần đồng thời và bạn chưa chọn ngôn ngữ, có lẽ một ngôn ngữ khác sẽ phù hợp hơn, hoặc có lẽ không. Xem xét phạm vi đầy đủ của các yêu cầu chức năng và phi chức năng (hoặc nhu cầu, mong muốn và mong muốn của người dùng) cho dự án của bạn và khả năng của các nền tảng phát triển khác nhau. Tại sao không sử dụng ThreadPool thay thế?Đa xử lý.Pool.ThreadPool hỗ trợ các nhóm các luồng, không giống như Multiprocessing.Pool hỗ trợ nhóm các quy trình, trong đó mỗi quy trình sẽ có một luồng.multiprocessing.pool.ThreadPool supports pools of threads, unlike the multiprocessing.Pool that supports pools of processes, where each process will have one thread. Chủ đề và quy trình khá khác nhau và việc chọn cái này hơn cái kia phải khá cố ý. Một chương trình Python là một quá trình có chủ đề chính. Bạn có thể tạo nhiều luồng bổ sung trong một quy trình Python. Bạn cũng có thể nĩa hoặc sinh ra nhiều quy trình Python, mỗi quy trình sẽ có một luồng chính và có thể sinh ra các luồng bổ sung. Nhìn rộng hơn, các luồng nhẹ và có thể chia sẻ bộ nhớ (dữ liệu và biến) trong một quy trình trong khi các quá trình là nặng nề và yêu cầu chi phí cao hơn và áp đặt nhiều giới hạn hơn trong việc chia sẻ bộ nhớ (dữ liệu và biến). Thông thường trong Python, các quy trình được sử dụng cho các nhiệm vụ và luồng liên kết CPU được sử dụng cho các nhiệm vụ gắn IO, và đây là một heuristic tốt, nhưng điều này không phải là trường hợp. Có lẽ Multiprocessing.Pool.ThreadPool phù hợp hơn với vấn đề cụ thể của bạn. Có lẽ hãy thử nó và xem. Tại sao không sử dụng Multiprocessing.Process thay thế?Đa xử lý.pool giống như chế độ tự động của người dùng cho các quy trình Python.multiprocessing.Pool is like the “automatic mode” for Python processes. Nếu bạn có một trường hợp sử dụng tinh vi hơn, bạn có thể cần sử dụng lớp đa xử lý trực tiếp.multiprocessing.Process class directly. Điều này có thể là do bạn yêu cầu đồng bộ hóa nhiều hơn giữa các quy trình với các cơ chế khóa, bộ nhớ được chia sẻ giữa các quy trình như người quản lý và/hoặc phối hợp nhiều hơn giữa các quy trình với các rào cản và semaphores. Có thể là bạn có một trường hợp sử dụng đơn giản hơn, chẳng hạn như một nhiệm vụ duy nhất, trong trường hợp đó có lẽ một nhóm quy trình sẽ là một giải pháp quá nặng. Điều đó đang được nói, nếu bạn thấy mình sử dụng lớp quy trình với từ khóa Target Target cho các chức năng thuần túy (các chức năng không có tác dụng phụ), có lẽ bạn sẽ phù hợp hơn với việc sử dụng đa xử lý.pool.Process class with the “target” keyword for pure functions (functions that don’t have side effects), perhaps you would be better suited to using the multiprocessing.Pool. Bạn có thể tìm hiểu thêm về sự khác biệt giữa nhóm đa xử lý và quy trình trong hướng dẫn:Pool and Process in the tutorial:
Tại sao không sử dụng ProcessPoolExecutor thay thế?Python cung cấp hai nhóm công nhân dựa trên quy trình thông qua lớp đa xử lý.pool.pool và lớp đồng thời.futures.processPoolExecutor.multiprocessing.pool.Pool class and the concurrent.futures.ProcessPoolExecutor class. Các lớp đa xử lý.Pool và ProcessPoolExecutor rất giống nhau. Cả hai đều là nhóm quy trình của các quy trình lao động trẻ em.multiprocessing.Pool and ProcessPoolExecutor classes are very similar. They are both process pools of child worker processes. Những điểm tương đồng quan trọng nhất như sau:
Đa xử lý.Pool và ProcessPoolExecutor cũng khác nhau một cách tinh tế.multiprocessing.Pool and ProcessPoolExecutor are also subtly different. Chúng tôi khác biệt chính như sau: Sự khác biệt giữa hai nhóm quy trình này tập trung vào sự khác biệt trong API trên chính các lớp.
Bạn có thể tìm hiểu thêm về sự khác biệt giữa nhóm đa xử lý và ProcessPoolExecutor trong hướng dẫn:Pool and the ProcessPoolExecutor in the tutorial:
Tại sao không sử dụng asyncio?Asyncio có thể là một giải pháp thay thế cho việc sử dụng đa xử lý.Pool.ThreadPool hoặc ThreadPoolExecutor, nhưng có lẽ không phải là một lựa chọn tốt cho đa xử lý.pool.multiprocessing.pool.ThreadPool or ThreadPoolExecutor, but is probably not a good alternative for the multiprocessing.Pool. Asyncio được thiết kế để hỗ trợ số lượng lớn các hoạt động IO, có lẽ hàng chục ngàn đến hàng chục ngàn, tất cả trong một luồng. Nó đòi hỏi một mô hình lập trình thay thế, được gọi là lập trình phản ứng, có thể là thách thức cho người mới bắt đầu. Khi sử dụng đa xử lý.pool, bạn thường thực hiện các tác vụ ràng buộc CPU, không phù hợp khi sử dụng mô-đun Asyncio.multiprocessing.Pool, you are typically executing CPU-bound tasks, which are not appropriate when using the AsyncIO module. Đọc thêmPhần này liệt kê các tài nguyên bổ sung hữu ích về chủ đề này. Sách
Hướng dẫn liên quan
API
Người giới thiệu
Kết luậnĐây là một hướng dẫn lớn và bạn đã phát hiện ra rất chi tiết về cách thức đa xử lý.pool hoạt động và cách sử dụng tốt nhất trong dự án của bạn.multiprocessing.Pool works and how to best use it on your project. Bạn có thấy hướng dẫn này hữu ích không? Tôi rất thích biết.Vui lòng chia sẻ một từ tử tế trong các ý kiến dưới đây. Bạn đã sử dụng hồ bơi trong một dự án chưa? Tôi rất thích nghe về nó;Xin vui lòng cho tôi biết trong các ý kiến. Bạn có câu hỏi nào không? Để lại câu hỏi của bạn trong một bình luận bên dưới và tôi sẽ trả lời nhanh với lời khuyên tốt nhất của tôi. |