Trong hướng dẫn này, bạn sẽ khám phá mối quan hệ giữa nhóm đa xử lý và Khóa thông dịch viên toàn cầu trong Python
Bắt đầu nào
Mục lục
Nhóm đa xử lý bị ảnh hưởng bởi GIL?
Nhóm đa xử lý cung cấp một nhóm công nhân có thể tái sử dụng để thực hiện các tác vụ đặc biệt với tính đồng thời dựa trên quy trình
Một ví dụ về đa xử lý. Lớp nhóm có thể được tạo, chỉ định số lượng công nhân cần tạo, nếu không, số lượng công nhân mặc định sẽ được tạo để khớp với số lượng CPU hợp lý trong hệ thống
Sau khi được tạo, các tác vụ đặc biệt có thể được cấp cho nhóm để thực hiện thông qua Nhóm. áp dụng[] chức năng. Nhiều tác vụ có thể được thực hiện trong sách bằng cách gọi cùng một chức năng với các đối số khác nhau thông qua Nhóm. hàm map[]
Các tác vụ có thể được thực thi không đồng bộ trong nhóm thông qua Pool. apply_async[] và Pool. map_async[], cho phép người gọi tiếp tục các tác vụ khác
Sau khi quan tâm đến nhóm đa xử lý là liệu nó có bị ảnh hưởng bởi Khóa thông dịch viên toàn cầu hay không
Nếu các công nhân trong nhóm đa xử lý bị ảnh hưởng bởi GIL, nó sẽ giới hạn các loại tác vụ mà họ có thể thực thi song song với các tác vụ giải phóng GIL, chẳng hạn như chặn I/O
Mặt khác, nếu các công nhân nhóm đa xử lý không bị ảnh hưởng bởi GIL, thì các công nhân đó có thể thực thi các tác vụ tùy ý bằng cách sử dụng cơ chế song song thực sự
Nhóm đa xử lý có tuân theo GIL không?
Chạy các vòng lặp của bạn bằng cách sử dụng tất cả các CPU, tải xuống cuốn sách MIỄN PHÍ của tôi để tìm hiểu cách thực hiện
Khóa phiên dịch toàn cầu là gì?
Phần bên trong của trình thông dịch Python không an toàn cho luồng
Điều này có nghĩa là có thể có các điều kiện tương tranh giữa nhiều luồng trong một quy trình Python, có khả năng dẫn đến hành vi không mong muốn và dữ liệu bị hỏng
Do đó, trình thông dịch Python sử dụng Khóa thông dịch viên toàn cầu, viết tắt là GIL, để thực hiện các lệnh được thực thi bởi trình thông dịch Python [được gọi là mã byte Python] an toàn theo luồng
GIL là một mẫu lập trình trong trình thông dịch Python tham chiếu được gọi là CPython, mặc dù các khóa tương tự tồn tại trong các ngôn ngữ thông dịch khác, chẳng hạn như Ruby. Nó là một khóa theo nghĩa là nó sử dụng một nguyên hàm đồng bộ hóa được gọi là loại trừ lẫn nhau hoặc khóa mutex để đảm bảo rằng chỉ một luồng thực thi mới có thể thực thi các lệnh tại một thời điểm trong quy trình Python
Trong CPython, khóa trình thông dịch toàn cầu, hoặc GIL, là một mutex bảo vệ quyền truy cập vào các đối tượng Python, ngăn nhiều luồng thực thi mã byte Python cùng một lúc. GIL ngăn chặn các điều kiện chủng tộc và đảm bảo an toàn cho luồng
— Khóa phiên dịch toàn cầu, Python Wiki
Tác dụng của GIL là bất cứ khi nào một luồng trong chương trình Python muốn chạy, nó phải có khóa trước khi thực thi. Đây không phải là vấn đề đối với hầu hết các chương trình Python có một luồng thực thi duy nhất, được gọi là luồng chính
Nó có thể trở thành một vấn đề trong các chương trình Python đa luồng, chẳng hạn như các chương trình sử dụng luồng. Lớp chủ đề hoặc đồng thời. tương lai. Lớp ThreadPoolExecutor
Khóa được phát hành rõ ràng và được mua lại định kỳ bởi mỗi luồng Python, cụ thể là sau khoảng 100 lệnh bytecode được thực thi trong trình thông dịch. Điều này cho phép các luồng khác trong quy trình Python chạy, nếu có
Khóa cũng được giải phóng trong một số trường hợp, cho phép các luồng khác chạy
Một ví dụ quan trọng là khi một luồng thực hiện thao tác I/O, chẳng hạn như đọc hoặc ghi từ tài nguyên bên ngoài như tệp, ổ cắm hoặc thiết bị
May mắn thay, nhiều hoạt động có khả năng bị chặn hoặc chạy lâu, chẳng hạn như I/O, xử lý hình ảnh và xử lý số NumPy, xảy ra bên ngoài GIL. Do đó, chỉ trong các chương trình đa luồng dành nhiều thời gian bên trong GIL, diễn giải mã byte CPython, GIL mới trở thành nút cổ chai
— Khóa phiên dịch toàn cầu, Python Wiki
Khóa cũng được phát hành rõ ràng bởi một số thư viện Python của bên thứ ba khi thực hiện các thao tác tính toán tốn kém trong mã C, chẳng hạn như nhiều thao tác mảng trong NumPy
Trong CPython, do Khóa phiên dịch toàn cầu, chỉ một luồng có thể thực thi mã Python cùng một lúc [mặc dù một số thư viện định hướng hiệu suất nhất định có thể khắc phục hạn chế này]
— phân luồng — Song song dựa trên luồng
GIL là một giải pháp đơn giản và hiệu quả để đảm bảo an toàn luồng trong trình thông dịch Python, nhưng nó có nhược điểm chính là đa luồng hoàn toàn không được hỗ trợ bởi Python
Một giải pháp thay thế có thể là làm cho trình thông dịch trở nên an toàn theo luồng một cách rõ ràng bằng cách bảo vệ từng phần quan trọng. Điều này đã và thường dẫn đến hiệu suất của các chương trình Python đơn luồng kém hơn tới 30%
Thật không may, cả hai thử nghiệm đều cho thấy hiệu suất đơn luồng giảm mạnh [chậm hơn ít nhất 30%], do lượng khóa chi tiết cần thiết để bù đắp cho việc loại bỏ GIL
— Khóa phiên dịch toàn cầu Python, Python Wiki
Bây giờ chúng ta đã quen thuộc với GIL, hãy xem cách đa xử lý bị ảnh hưởng
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
Nhóm đa xử lý và Khóa thông dịch viên toàn cầu
Mô-đun đa xử lý cung cấp đồng thời dựa trên quy trình không bị giới hạn bởi Khóa phiên dịch toàn cầu
Cả luồng và quy trình đều có thể thực thi đồng thời [không theo thứ tự], nhưng chỉ các quy trình python mới có thể thực thi song song [đồng thời], không phải luồng Python [với một số lưu ý]
Điều này có nghĩa là nếu chúng ta muốn mã Python chạy trên tất cả các lõi CPU và tận dụng tốt nhất phần cứng hệ thống của mình, chúng ta nên sử dụng đồng thời dựa trên quy trình
Gói đa xử lý cung cấp cả đồng thời cục bộ và từ xa, hỗ trợ hiệu quả Khóa thông dịch viên toàn cầu bằng cách sử dụng các quy trình con thay vì các luồng. Do đó, mô-đun đa xử lý cho phép lập trình viên tận dụng tối đa nhiều bộ xử lý trên một máy nhất định. Nó chạy trên cả Unix và Windows
— đa xử lý — Song song dựa trên quy trình
Trên thực tế, Jesse Noller và Richard Oudkerk đã đề xuất và phát triển mô-đun đa xử lý [ban đầu được gọi là “pyprocessing”] bằng Python để khắc phục những hạn chế và hỗ trợ GIL
Gói pyprocessing cung cấp một phương pháp để hỗ trợ GIL, cho phép các ứng dụng trong CPython tận dụng lợi thế của kiến trúc đa lõi mà không yêu cầu người dùng thay đổi hoàn toàn mô hình lập trình của họ [i. e. bỏ lập trình luồng cho một cách tiếp cận “đồng thời” khác - Twisted, Actors, v.v.]
— PEP 371 – Bổ sung gói đa xử lý vào thư viện chuẩn
Điều này bao gồm đa xử lý. Lớp nhóm được giới thiệu với mô-đun đa xử lý trong Python 2. 6 và 3. 0
Nhóm đa xử lý không bị giới hạn bởi Khóa phiên dịch toàn cầu và có thể đạt được tính song song thực sự trong Python
Khóa học nhóm đa xử lý Python miễn phí
Tải xuống bảng cheat API Pool của tôi và như một phần thưởng, bạn sẽ có quyền truy cập MIỄN PHÍ vào khóa học email 7 ngày của tôi
Khám phá cách sử dụng Nhóm đa xử lý bao gồm cách định cấu hình số lượng công nhân và cách thực thi các tác vụ không đồng bộ