Hướng dẫn threadpoolexecutor python - threadpoolexecutor python
Thứ ba, 23/06/2020 | 00:00 GMT+7 Show
Các chuỗi Python là một dạng song song cho phép chương trình của bạn chạy nhiều thủ tục cùng một lúc. Tính song song trong Python cũng có thể đạt được bằng cách sử dụng nhiều quy trình, nhưng các stream đặc biệt phù hợp để tăng tốc các ứng dụng liên quan đến lượng I / O (đầu vào / kết quả ) đáng kể. Ví dụ về hoạt động liên kết I / O bao gồm thực hiện các yêu cầu web và đọc dữ liệu từ các file . Ngược lại với các hoạt động ràng buộc I / O, các hoạt động ràng buộc CPU (như thực hiện phép toán với thư viện chuẩn Python) sẽ không được hưởng lợi nhiều từ các stream Python. Python 3 bao gồm tiện ích 5 để thực thi mã trong một stream .Trong hướng dẫn này, ta sẽ sử dụng 5 để thực hiện các yêu cầu mạng một cách nhanh chóng. Ta sẽ xác định một hàm rất phù hợp để gọi trong các stream , sử dụng 5 để thực thi chức năng đó và xử lý kết quả từ các lần thực thi đó.Đối với hướng dẫn này, ta sẽ thực hiện các yêu cầu mạng để kiểm tra sự tồn tại của các trang Wikipedia .
Lưu ý: Thực tế là các hoạt động liên kết I / O được hưởng lợi nhiều hơn từ các stream so với các hoạt động liên kết CPU là do một đặc điểm riêng trong Python được gọi là khóa thông dịch toàn cục . Nếu muốn, bạn có thể tìm hiểu thêm về khóa thông dịch global của Python trong tài liệu Python chính thức . Thực tế là các hoạt động liên kết I / O được hưởng lợi nhiều hơn từ các stream so với các hoạt động liên kết CPU là do một đặc điểm riêng trong Python được gọi là khóa thông dịch toàn cục . Nếu muốn, bạn có thể tìm hiểu thêm về khóa thông dịch global của Python trong tài liệu Python chính thức
. Yêu cầuĐể tận dụng tối đa hướng dẫn này, bạn nên làm quen với lập trình bằng Python và môi trường lập trình Python local với 8 được cài đặt.Bạn có thể xem lại các hướng dẫn này để biết thông tin cơ bản cần thiết:
Bước 1 - Xác định một hàm để thực thi trong chuỗiHãy bắt đầu bằng cách xác định một hàm mà ta muốn thực thi với sự trợ giúp của các stream . Sử dụng 0 hoặc môi trường phát triển / soạn thảo văn bản bạn muốn , bạn có thể mở file này:
Đối với hướng dẫn này, ta sẽ viết một hàm xác định xem trang Wikipedia có tồn tại hay không: wiki_page_ Chức năng.py
Các 1 chức năng chấp nhận hai đối số: một URL đến một trang Wikipedia ( 2 ), và một 3 số giây để chờ đợi một phản ứng từ URL đó.
1 sử dụng gói 8 để thực hiện yêu cầu web tới URL đó. Tùy thuộc vào mã trạng thái của 6 HTTP, một chuỗi được trả về mô tả trang có tồn tại hay không. Các mã trạng thái khác nhau thể hiện các kết quả khác nhau của một yêu cầu HTTP. Quy trình này giả định mã trạng thái 7 "thành công" nghĩa là trang Wikipedia tồn tại và mã trạng thái 8 "không tìm thấy" nghĩa là trang Wikipedia không tồn tại.Như được mô tả trong phần Yêu cầu , bạn cần cài đặt gói 8 để chạy chức năng này.Hãy thử chạy hàm bằng cách thêm 0 và lệnh gọi hàm sau hàm 1 :wiki_page_ Chức năng.py
Các 1 chức năng chấp nhận hai đối số: một URL đến một trang Wikipedia ( 2 ), và một 3 số giây để chờ đợi một phản ứng từ URL đó.
1 sử dụng gói 8 để thực hiện yêu cầu web tới URL đó. Tùy thuộc vào mã trạng thái của 6 HTTP, một chuỗi được trả về mô tả trang có tồn tại hay không. Các mã trạng thái khác nhau thể hiện các kết quả khác nhau của một yêu cầu HTTP. Quy trình này giả định mã trạng thái 7 "thành công" nghĩa là trang Wikipedia tồn tại và mã trạng thái 8 "không tìm thấy" nghĩa là trang Wikipedia không tồn tại.
Như được mô tả trong phần Yêu cầu , bạn cần cài đặt gói 8 để chạy chức năng này.
Hãy thử chạy hàm bằng cách thêm 0 và lệnh gọi hàm sau hàm 1 : Khi bạn đã thêm mã, hãy lưu file . Nói chung, không an toàn khi chia sẻ các đối tượng hoặc trạng thái Python giữa các stream mà không cần chú ý đặc biệt để tránh các lỗi đồng thời. Khi xác định một hàm
để thực thi trong một stream , cách tốt nhất là xác định một hàm thực hiện một công việc duy nhất và không chia sẻ hoặc xuất bản trạng thái cho các stream khác. Nếu ta chạy mã này:Ta sẽ thấy kết quả như sau: Việc gọi hàm 1 với một trang Wikipedia hợp lệ sẽ trả về một chuỗi xác nhận trên thực tế, trang đó tồn tại.wiki_page_ Chức năng.py
Các 1 chức năng chấp nhận hai đối số: một URL đến một trang Wikipedia ( 2 ), và một 3 số giây để chờ đợi một phản ứng từ URL đó.
Ta sẽ thấy kết quả như sau:
Như được mô tả trong phần Yêu cầu , bạn cần cài đặt gói 8 để chạy chức năng này.
Hãy thử chạy hàm bằng cách thêm 0 và lệnh gọi hàm sau hàm 1 :Bước 3 - Xử lý ngoại lệ từ các hàm chạy trong chuỗiTrong bước trước, 1 đã trả về thành công một giá trị cho tất cả các lệnh gọi của ta . Trong bước này, ta sẽ thấy rằng 5 cũng có thể nêu ra các ngoại lệ được tạo trong các lệnh gọi hàm stream .Hãy xem xét khối mã ví dụ sau: wiki_page_ Chức năng.py
Khối mã này gần giống với khối mà ta đã sử dụng ở Bước 2, nhưng nó có hai điểm khác biệt chính:
Nếu ta chạy lại chương trình, ta sẽ thấy kết quả sau: 0Bốn thông báo 9 được in — một thông báo cho mỗi 3 của ta , vì không ai trong số chúng có thể hoàn thành trong 8 giây và mỗi lệnh trong bốn 1 gọi 1 đã nêu ra ngoại lệ 9 .Đến đây bạn đã thấy rằng nếu một lệnh gọi hàm được gửi đến 5 tạo ra một ngoại lệ, thì ngoại lệ đó có thể được nâng lên bình thường bằng cách gọi 9 . Gọi 9 trên tất cả các lệnh gọi đã gửi của bạn đảm bảo chương trình của bạn sẽ không bỏ lỡ bất kỳ trường hợp ngoại lệ nào được nêu ra từ hàm stream của bạn.Bước 4 - So sánh thời gian thực thi có và không có streamBây giờ hãy xác minh việc sử dụng 5 thực sự làm cho chương trình của bạn nhanh hơn.Đầu tiên, hãy dành thời gian 1 nếu ta chạy nó mà không có chuỗi:wiki_page_ Chức năng.py 1Khối mã này gần giống với khối mà ta đã sử dụng ở Bước 2, nhưng nó có hai điểm khác biệt chính: Bây giờ ta vượt qua 5 để 1 . Vì gói 8 sẽ không thể hoàn thành yêu cầu web của nó tới Wikipedia trong 8 giây, nên nó sẽ đưa ra một ngoại lệ 9 . 2Ta bắt các ngoại lệ 9 được nêu ra bởi 1 và in ra một chuỗi mỗi lần ta làm như vậy.Nếu ta chạy lại chương trình, ta sẽ thấy kết quả sau: Bốn thông báo 9 được in — một thông báo cho mỗi 3 của ta , vì không ai trong số chúng có thể hoàn thành trong 8 giây và mỗi lệnh trong bốn 1 gọi 1 đã nêu ra ngoại lệ 9 .wiki_page_ Chức năng.py 3Khối mã này gần giống với khối mà ta đã sử dụng ở Bước 2, nhưng nó có hai điểm khác biệt chính: Bây giờ ta vượt qua 5 để 1 . Vì gói 8 sẽ không thể hoàn thành yêu cầu web của nó tới Wikipedia trong 8 giây, nên nó sẽ đưa ra một ngoại lệ 9 . 4Ta bắt các ngoại lệ 9 được nêu ra bởi 1 và in ra một chuỗi mỗi lần ta làm như vậy.Nếu ta chạy lại chương trình, ta sẽ thấy kết quả sau: Bốn thông báo 9 được in — một thông báo cho mỗi 3 của ta , vì không ai trong số chúng có thể hoàn thành trong 8 giây và mỗi lệnh trong bốn 1 gọi 1 đã nêu ra ngoại lệ 9 .Đến đây bạn đã thấy rằng nếu một lệnh gọi hàm được gửi đến nano wiki_page_function.py 5 tạo ra một ngoại lệ, thì ngoại lệ đó có thể được nâng lên bình thường bằng cách gọi import requests import concurrent.futures def get_wiki_page_existence(wiki_page_url, timeout=10): response = requests.get(url=wiki_page_url, timeout=timeout) page_status = "unknown" if response.status_code == 200: page_status = "exists" elif response.status_code == 404: page_status = "does not exist" return wiki_page_url + " - " + page_status wiki_page_urls = [ "https://en.wikipedia.org/wiki/Ocean", "https://en.wikipedia.org/wiki/Island", "https://en.wikipedia.org/wiki/this_page_does_not_exist", "https://en.wikipedia.org/wiki/Shark", ] with concurrent.futures.ThreadPoolExecutor() as executor: futures = [] for url in wiki_page_urls: futures.append(executor.submit(get_wiki_page_existence, wiki_page_url=url)) for future in concurrent.futures.as_completed(futures): print(future.result()) 9 . Gọi import requests import concurrent.futures def get_wiki_page_existence(wiki_page_url, timeout=10): response = requests.get(url=wiki_page_url, timeout=timeout) page_status = "unknown" if response.status_code == 200: page_status = "exists" elif response.status_code == 404: page_status = "does not exist" return wiki_page_url + " - " + page_status wiki_page_urls = [ "https://en.wikipedia.org/wiki/Ocean", "https://en.wikipedia.org/wiki/Island", "https://en.wikipedia.org/wiki/this_page_does_not_exist", "https://en.wikipedia.org/wiki/Shark", ] with concurrent.futures.ThreadPoolExecutor() as executor: futures = [] for url in wiki_page_urls: futures.append(executor.submit(get_wiki_page_existence, wiki_page_url=url)) for future in concurrent.futures.as_completed(futures): print(future.result()) 9 trên tất cả các lệnh gọi đã gửi của bạn đảm bảo chương trình của bạn sẽ không bỏ lỡ bất kỳ trường hợp ngoại lệ nào được nêu ra từ hàm stream của bạn.Bước 4 - So sánh thời gian thực thi có và không có stream Bây giờ hãy xác minh việc sử dụng 5 thực sự làm cho chương trình của bạn nhanh hơn.Đầu tiên, hãy dành thời gian 1 nếu ta chạy nó mà không có chuỗi: Trong ví dụ mã, ta gọi hàm Nếu ta chạy lại mã này như trước, ta sẽ thấy kết quả như sau: |