Hướng dẫn why is python not multithreaded? - tại sao python không đa luồng?

Trong bài viết này, trước tiên tôi sẽ hướng dẫn bạn sự khác biệt giữa lập trình đồng thời và thực hiện song song, thảo luận về các cơ chế lập trình đồng thời của Python và những cạm bẫy của đa luồng trong Python.

Hiểu lập trình đồng thời so với thực hiện song song

Lập trình đồng thời không tương đương với việc thực hiện song song, mặc dù thực tế là hai thuật ngữ này thường được sử dụng thay thế cho nhau.

Minh họa về sự đồng thời mà không có sự song song

Đồng thời là một thuộc tính mà nhiều hơn một thao tác có thể được chạy đồng thời nhưng nó không có nghĩa là nó sẽ có. [Hãy tưởng tượng nếu bộ xử lý của bạn là một luồng đơn.]

Minh họa song song

Song song là một thuộc tính mà các hoạt động thực sự đang được chạy đồng thời. Nó thường được xác định bởi các ràng buộc phần cứng.

Hãy nghĩ về chương trình của bạn như một chuỗi thức ăn nhanh, đồng thời được kết hợp khi hai bộ đếm riêng biệt cho đơn hàng và thu thập được xây dựng. Tuy nhiên, nó không đảm bảo sự song song vì nó phụ thuộc vào số lượng nhân viên có sẵn. Nếu chỉ có một nhân viên xử lý cả yêu cầu đặt hàng và thu thập, các hoạt động có thể chạy song song. Sự song song chỉ có mặt khi có hai nhân viên phục vụ đồng thời và thu thập.

Python xây dựng

Bây giờ, chúng ta có gì ở Python? Liệu Python đã xây dựng các kết quả tạo điều kiện cho chúng ta xây dựng các chương trình đồng thời và cho phép chúng chạy song song?

Trong các cuộc thảo luận sau đây, chúng tôi giả sử các chương trình của chúng tôi đều được viết và chạy trong bộ xử lý đa luồng hoặc đa lõi.

Câu trả lời là Jein [có và không trong tiếng Đức]. Tại sao có? Python có các thư viện tích hợp cho các cấu trúc lập trình đồng thời phổ biến nhất-đa xử lý và đa luồng. Bạn có thể nghĩ, vì Python hỗ trợ cả hai, tại sao Jein? Lý do là, đa luồng trong Python không thực sự là đa luồng, do Gil trong Python.Jein [Yes and No in German]. Why yes? Python does have built-in libraries for the most common concurrent programming constructs — multiprocessing and multithreading. You may think, since Python supports both, why Jein? The reason is, multithreading in Python is not really multithreading, due to the GIL in Python.

Đa luồng-song song dựa trên chủ đề

threading là gói cung cấp API để tạo và quản lý các luồng. Các chủ đề trong Python luôn không xác định và lịch trình của chúng được thực hiện bởi hệ điều hành. Tuy nhiên, đa luồng có thể không làm những gì bạn mong đợi.

Tại sao đa luồng trong Python có thể không phải là những gì bạn & nbsp; muốn?

Khác với những cạm bẫy phổ biến như bế tắc, chết đói trong đa luồng nói chung. Python nổi tiếng với hiệu suất kém trong đa luồng.

Chúng ta hãy nhìn vào đoạn trích sau:

nhập luồng

Def Countdown []: x = 1000000000 trong khi x> 0: x -= 1

# Triển khai 1: Multi-threadingDef Triển khai_1 []: Thread_1 = Threading.Thread [Target = Countdown] Thread_2 = Threading.Thread [Target = Countdown] Thread_1.Start [] Thread_2.start [] ]

# Triển khai 2: Chạy trong Triển khai Serialdef_2 []: Đếm ngược [] Đếm ngược []

Việc thực hiện nào sẽ nhanh hơn? Hãy để chúng tôi thực hiện một thời gian.

Kết quả thời gian của cả hai triển khai

Đáng ngạc nhiên, chạy 2 countdown[] vượt trội so với đa luồng? Làm sao điều này xảy ra được? Nhờ khóa thông dịch viên toàn cầu khét tiếng [GIL].

Thuốc phiên dịch toàn cầu là gì & nbsp; [GIL] là gì?

Phụ thuộc vào sự phân phối của Python của bạn, mà hầu hết các trường hợp, là một triển khai của CPython. CPython là triển khai ban đầu của Python, bạn có thể đọc thêm về nó trong chuỗi StackOverflow này.

Trong Cpython, đa luồng được hỗ trợ bằng cách giới thiệu một mutex được gọi là khóa phiên dịch toàn cầu [còn gọi là Gil]. Đó là để ngăn chặn nhiều luồng truy cập cùng một đối tượng Python cùng một lúc. Điều này có ý nghĩa, bạn sẽ không muốn người khác đột biến đối tượng của bạn trong khi bạn đang xử lý nó.

Minh họa thực hiện_1

Vì vậy, từ đoạn mã của chúng tôi ở trên, implementation_1 tạo ra 2 luồng và được cho là chạy song song trên một hệ thống đa luồng. Tuy nhiên, chỉ có một luồng có thể giữ GIL tại một thời điểm, một luồng phải đợi một luồng khác để giải phóng GIL trước khi chạy. Trong khi đó, lập lịch và chuyển đổi được thực hiện bởi hệ điều hành giới thiệu chi phí làm cho implementation_1 thậm chí chậm hơn.

Làm thế nào để bỏ qua & nbsp; gil?

Làm thế nào chúng ta có thể bỏ qua Gil, trong khi duy trì việc sử dụng đa luồng? Không có câu trả lời tốt cho câu hỏi này, vì điều này thay đổi theo mục đích của mã của bạn.

Sử dụng một triển khai khác của Python như Jython, Pypy hoặc IronPython là một lựa chọn. Cá nhân tôi không ủng hộ việc sử dụng một triển khai Python khác vì hầu hết các thư viện được viết không được kiểm tra chống lại các triển khai khác nhau của Python.

Một cách giải quyết tiềm năng khác là sử dụng C-Extension, hoặc được gọi là Cython. Lưu ý rằng Cython và Cpython không giống nhau. Bạn có thể đọc thêm về Cython ở đây.

Sử dụng đa xử lý thay thế. Kể từ khi đa xử lý, một thông dịch viên được tạo cho mỗi quá trình trẻ em. Tình huống mà các chủ đề đấu tranh cho Gil Simple không tồn tại vì luôn luôn có một chủ đề chính trong mọi quy trình.

Bất chấp tất cả những cạm bẫy, chúng ta vẫn nên sử dụng đa luồng?

Nếu nhiệm vụ của bạn là I/O bị ràng buộc, có nghĩa là luồng dành phần lớn thời gian để xử lý I/O như thực hiện các yêu cầu mạng. Vẫn là hoàn toàn tốt khi sử dụng đa luồng làm chủ đề, hầu hết thời gian, bị chặn và đưa vào hàng đợi bị chặn bởi HĐH. Chủ đề cũng luôn luôn đói tài nguyên hơn quá trình.

Đa xử lý-song song dựa trên quy trình

Hãy để chúng tôi thực hiện đoạn mã trước đây của chúng tôi bằng cách sử dụng đa xử lý.

Nhập đa xử lý

# Countdown [] được định nghĩa trong đoạn trích trước.

DEF THỰC HIỆN_3 []: Process_1 = MultipRocessing.Process [Target = Countdown] Process_2 = Multiprocessing.Process [Target = Countdown] Process_1.start [] Process_2.start []

Kết quả là bản thân là tự giải thích.

Kết quả thời gian của đa bộ xử lý so với đa luồng

Sự kết luận

Hạn chế của Gil là một cái gì đó đã bắt tôi ngay từ đầu thời gian là một nhà phát triển Python. Tôi đã nhận thức được quyết định của tôi về việc sử dụng chủ đề là hoàn toàn vô giá trị cho đến khi tôi thực hiện thời gian. Tôi hy vọng bài viết này sẽ giúp.

Vui lòng nhấp vào nút 👏 nếu bạn thấy điều này hữu ích.

ĐANG TẢI. . . Nhận xét và nhiều hơn nữa!
. . . comments & more!

Python có thực sự đa luồng không?

Python không phải là ngôn ngữ đơn. Các quá trình Python thường sử dụng một luồng duy nhất vì GIL. Mặc dù GiL, các thư viện thực hiện các nhiệm vụ nặng về tính toán như Numpy, Scipy và Pytorch sử dụng các triển khai dựa trên C dưới mui xe, cho phép sử dụng nhiều lõi.. Python processes typically use a single thread because of the GIL. Despite the GIL, libraries that perform computationally heavy tasks like numpy, scipy and pytorch utilise C-based implementations under the hood, allowing the use of multiple cores.

Tại sao Python không an toàn?

Python không an toàn cho luồng và ban đầu được thiết kế với một thứ gọi là Gil, hoặc khóa thông dịch toàn cầu, đảm bảo các quy trình được thực thi theo chiều cao trên CPU của máy tính.Nhìn bề ngoài, điều này có nghĩa là các chương trình Python không thể hỗ trợ đa xử lý.originally designed with something called the GIL, or Global Interpreter Lock, that ensures processes are executed serially on a computer's CPU. On the surface, this means Python programs cannot support multiprocessing.

Python có đa luồng theo mặc định không?

Theo mặc định, đa luồng theo mặc định, các chương trình Python của bạn có một luồng duy nhất, được gọi là luồng chính.Bạn có thể tạo các luồng bằng cách chuyển một hàm cho hàm tạo luồng [] hoặc bằng cách kế thừa lớp luồng và ghi đè phương thức Run [].By default, your Python programs have a single thread, called the main thread. You can create threads by passing a function to the Thread[] constructor or by inheriting the Thread class and overriding the run[] method.

Các chủ đề Python có thể chạy trên nhiều lõi không?

Chủ đề Python không thể tận dụng nhiều lõi.Điều này là do một chi tiết triển khai nội bộ được gọi là GIL [khóa thông dịch viên toàn cầu] trong việc triển khai C của Python [CPython], gần như chắc chắn là những gì bạn sử dụng.. This is due to an internal implementation detail called the GIL [global interpreter lock] in the C implementation of python [cPython] which is almost certainly what you use.

Chủ Đề