Hướng dẫn python multithreading append to list - python đa luồng nối thêm vào danh sách
Bản tóm tắt Show
Tại sao đầu ra là lộn xộn? ==> Bởi vì một luồng có thể mang lại một phần thông qua việc thực thi câu lệnh Tại sao ==> Bởi vì nội dung của Đầu ra Đầu ra là lộn xộn vì nó đang được tạo ra bởi câu lệnh Ví dụ: mã này:
Sản xuất đầu ra xen kẽ này:
Hành vi xen kẽ có thể được ngăn chặn bằng cách sử dụng 0:
Nội dung của danh sách Nội dung cuối cùng của 2 nếu câu lệnh 3được thực thi về mặt nguyên tử, đó là không có luồng hiện tại mang lại cho một luồng khác cũng đang đọc và nối lại đến Tuy nhiên đây không phải là cách chủ đề hoạt động. Một luồng có thể mang lại sau khi đọc phần tử cuối cùng từ
Điều này để lại 9Như với các câu lệnh 0 trước khi thực hiện 3. Takeaways thread-safe list by using a mutual exclusion (mutex) lock via the threading.Lock class. Bây giờ bạn đã biết cách sử dụng một danh sách an toàn chủ đề trong Python. Bạn có câu hỏi nào không? Đặt câu hỏi của bạn trong các ý kiến dưới đây và tôi sẽ cố gắng hết sức để trả lời.
Ảnh của Harley-Davidson trên unplashNhiều chủ đề có thể nối vào một danh sách trong Python không? Chúng ta có thể nối một cách an toàn vào một tệp từ nhiều luồng bằng khóa loại trừ lẫn nhau. Python cung cấp một khóa loại trừ lẫn nhau, còn được gọi là mutex, thông qua luồng. LỚP LỚN. Đầu tiên, chúng ta có thể tạo một thể hiện của khóa để được chia sẻ bởi tất cả các luồng. Đang nối vào một luồng danh sách Mặc dù danh sách trong đa luồng là không an toàn, nhưng nó an toàn theo luồng theo hoạt động của phụ lục.threading.Thread class. Là chủ đề danh sách
Trong lập trình đồng thời, chúng ta có thể cần chia sẻ cấu trúc dữ liệu danh sách giữa các luồng. Nhiều luồng có thể cần nối dữ liệu vào cùng một danh sách, các luồng khác có thể muốn xóa các mục hoặc kiểm tra độ dài của danh sách. Là danh sách an toàn trong Python và nếu không, làm thế nào chúng ta có thể làm cho nó an toàn? Hầu hết các hoạt động danh sách là nguyên tửNhiều hoạt động phổ biến trong danh sách là nguyên tử, có nghĩa là chúng an toàn cho luồng. Nhớ lại, một danh sách là một ví dụ của lớp danh sách.List class. Nguyên tử có nghĩa là hoạt động xảy ra hoặc không xảy ra không có ở giữa trạng thái không nhất quán. Các hoạt động như thêm, xóa và đọc một giá trị trong danh sách là nguyên tử.
Specifically:
Bạn có thể tìm hiểu về các hoạt động nguyên tử trong Python tại đây:
Bởi vì các hoạt động nguyên tử xảy ra hoặc không xảy ra, điều đó có nghĩa là chúng an toàn cho luồng. Cụ thể, sử dụng bất kỳ hoạt động nào ở trên trong danh sách được chia sẻ giữa nhiều luồng sẽ không dẫn đến điều kiện chủng tộc, tham nhũng của danh sách hoặc tham nhũng dữ liệu trong danh sách. Tiếp theo, hãy để Lừa xem xét lý do tại sao dựa vào các hoạt động danh sách nguyên tử có thể mong manh. Bị nhầm lẫn bởi API mô -đun luồng? Tải xuống bảng cheat pdf miễn phí của tôi Hoạt động danh sách nguyên tử rất dễ vỡCác hoạt động phổ biến trong danh sách là nguyên tử và do đó chủ đề an toàn như chúng ta đã thấy trong phần trước. Điều này chỉ đúng tại thời điểm viết vì một vài cân nhắc cụ thể, chẳng hạn như:
Điều này có nghĩa là tùy thuộc vào an toàn chủ đề của các hoạt động này có thể mong manh trong các phiên bản Python trong tương lai hoặc khi thực hiện chương trình Python của bạn với các phiên dịch viên Python thay thế. Đây không phải là một mối quan tâm nhỏ. Có những nỗ lực phát triển thường xuyên để cải thiện thông dịch viên Python và thậm chí cố gắng loại bỏ Gil. Những điều này có thể sẽ thay đổi các chi tiết cụ thể của VM Python, biên dịch mã byte và an toàn chủ đề của các cấu trúc dữ liệu tích hợp. Nó cũng đang trở nên phổ biến hơn để chạy mã Python bằng cách sử dụng các phiên dịch viên của bên thứ ba, chủ yếu để đạt được hiệu suất tốt hơn. Thông dịch viên thay thế có thể hoặc không thể thực hiện các quy tắc tương tự cho các hoạt động nguyên tử trong danh sách. Do đó, chúng tôi có thể mong muốn một danh sách Python an toàn chủ đề là chống lại các thay đổi đối với các phiên dịch viên Python và GIL.
Nối thêm một giá trị thông qua append (). Thêm một danh sách vào một danh sách thông qua mở rộng (). Gán nhiều giá trị của một danh sách thông qua một lát. Nhận một giá trị từ một danh sách thông qua ký hiệu khung []. Xóa giá trị cuối cùng khỏi danh sách thông qua pop (). Sắp xếp một danh sách thông qua sắp xếp ().Bạn có thể tìm hiểu về các hoạt động nguyên tử trong Python tại đây: Hoạt động nguyên tử chủ đề trong Python Bởi vì các hoạt động nguyên tử xảy ra hoặc không xảy ra, điều đó có nghĩa là chúng an toàn cho luồng. Cụ thể, sử dụng bất kỳ hoạt động nào ở trên trong danh sách được chia sẻ giữa nhiều luồng sẽ không dẫn đến điều kiện chủng tộc, tham nhũng của danh sách hoặc tham nhũng dữ liệu trong danh sách.threading.Lock can be used to protect the list. Tiếp theo, hãy để Lừa xem xét lý do tại sao dựa vào các hoạt động danh sách nguyên tử có thể mong manh.
Hoạt động danh sách nguyên tử rất dễ vỡ Các hoạt động phổ biến trong danh sách là nguyên tử và do đó chủ đề an toàn như chúng ta đã thấy trong phần trước.
Việc sử dụng trình thông dịch Python tham chiếu. Việc sử dụng khóa phiên dịch toàn cầu (GIL) trong trình thông dịch Python tham chiếu. Các hoạt động phổ biến trong danh sách là nguyên tử và do đó chủ đề an toàn như chúng ta đã thấy trong phần trước.
Các chi tiết chính xác về cách các hoạt động danh sách này được chuyển đổi thành mã byte của máy ảo Python. Việc sử dụng trình thông dịch Python tham chiếu. Điều này có thể đạt được thông qua lớp Threading.Rlock. Nó sẽ cho phép khóa được thu được bởi cùng một luồng một lần nữa.threading.RLock class. It will allow the lock to be acquired by the same thread again. Bạn có thể tìm hiểu thêm về khóa reentrant ở đây:
Hãy để phát triển một lớp kết thúc một số hoạt động danh sách phổ biến theo cách an toàn cho luồng. Một cách tiếp cận sẽ là ghi đè lớp Danh sách và triển khai các phiên bản an toàn luồng của tất cả hoặc một tập hợp con của các chức năng.List class and implement thread-safe versions of all or a subset of functions. Một cách tiếp cận khác là xác định một lớp mới có cùng giao diện với lớp Danh sách, ngoại trừ các chức năng trên lớp là an toàn cho luồng.List class, except the functions on the class are threads-safe. Cách tiếp cận cuối cùng là xác định một lớp mới với các hoạt động giống như danh sách, có thể không giống với giao diện của lớp Danh sách.List class. Tôi thích cách tiếp cận thứ hai để làm rõ cho người dùng của lớp rằng họ đang làm việc với một cái gì đó khác biệt. Nó không phải là một sự thay thế khe cắm cho danh sách an toàn, nó là một cấu trúc dữ liệu được thiết kế cho một trường hợp sử dụng an toàn luồng phải được xử lý một cách cực kỳ chăm sóc.List that is thread safe, it is a data structure designed for a thread-safe use case that must be treated with extreme care. Đầu tiên, chúng ta có thể xác định lớp với một tên rõ ràng như ThreadSafelist.ThreadSafeList.
Tiếp theo, chúng ta có thể xác định một hàm tạo khởi tạo cả danh sách nội bộ và khóa được sử dụng để bảo vệ danh sách dưới dạng các biến thể hiện trên lớp.
Tiếp theo, chúng ta có thể bắt đầu thêm chức năng mà chúng ta có thể cần trong ứng dụng của mình. Trong trường hợp này, chúng tôi sẽ cung cấp bốn hoạt động trong danh sách:
Mỗi thao tác trong danh sách sẽ được khóa bởi khóa bằng giao diện Trình quản lý ngữ cảnh. Giao diện trình quản lý bối cảnh được ưa thích như một hoạt động trong danh sách có thể gây ra lỗi (ví dụ: chỉ mục ra khỏi giới hạn) và chúng tôi cần đảm bảo rằng khóa sẽ luôn được phát hành, bất kể thành công hay thất bại của hoạt động. Ví dụ: phương pháp cho hoạt động phụ lục được liệt kê dưới đây.
Các phương pháp cho các hoạt động POP, GET và LENGTH được liệt kê dưới đây.
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; Các phương pháp cho các hoạt động POP, GET và LENGTH được liệt kê dưới đây. # Xóa và trả về giá trị cuối cùng khỏi danh sách def pop (tự):
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;sort() and extend(). & nbsp; & nbsp; & nbsp; & nbsp;# đọc một giá trị từ danh sách tại một chỉ mụcindex() or reverse(). & nbsp; & nbsp; & nbsp; & nbsp; def get (self, index): & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;& nbsp; & nbsp; & nbsp; & nbsp;# Trả về số lượng mục trong danh sách & nbsp; & nbsp; & nbsp; & nbsp; độ dài def (self): Là một tiện ích mở rộng, hãy thử thêm một số hoạt động bổ sung mà bạn muốn sử dụng trong danh sách của mình như Sort () và Extend (). Ngoài ra, hãy cố gắng thêm một số hoạt động liên quan đến các hoạt động tổng hợp trong danh sách, như index () hoặc larter (). Tiếp theo, hãy để Lừa trình diễn an toàn chủ đề của danh sách trong một ví dụ đã làm việc.ThreadSafeList, then loop 100,000 times, adding a value to the list each iteration. Ví dụ về danh sách an toàn chủ đềadd_items() function below implements this.
Một lần nữa, điều này có thể đạt được với danh sách Python mặc định bằng phiên bản hiện tại (v3.10) của trình thông dịch Python tham chiếu, nhưng nó có thể hoặc không phải là bằng chứng trong tương lai cho các thay đổi trong trình thông dịch. Do đó, chúng tôi sẽ sử dụng lớp danh sách an toàn chủ đề của chúng tôi được phát triển trong phần trước.
Hàm add_items () bên dưới thực hiện điều này.add_items() function and be passed the same ThreadSafeList as an argument. # Thêm các mục vào danh sách
Hàm add_items () bên dưới thực hiện điều này.
# Thêm các mục vào danh sách
# Thêm các mục vào danh sách
# Thêm các mục vào danh sách
# Tạo danh sách an toàn chủ đề # Định cấu hình các luồng để thêm vào danh sách # Bắt đầu chủ đề Inthreads forthreads:ThreadSafeList class might be to add a function so that a thread can get the lock once and add many items to the list in batch. # Đợi tất cả các luồng chấm dứt in ('Chờ các chủ đề chính ...') # Báo cáo số lượng mục trong danh sách
Sau đó, chúng tôi định cấu hình và bắt đầu mười luồng, mỗi chủ đề rất cố gắng thêm 100.000 mục vào danh sách. Mỗi cuộc gọi để nối () trên danh sách an toàn luồng được bảo vệ bởi khóa, đảm bảo rằng chỉ có một luồng có thể thêm một mục vào danh sách tại một thời điểm.Một cải tiến hữu ích cho lớp ThreadSafelist có thể là thêm một hàm để một luồng có thể lấy khóa một lần và thêm nhiều mục vào danh sách theo đợt. Các luồng chính chặn cho đến khi tất cả mười luồng mới chấm dứt. Cuối cùng, tất cả các chủ đề kết thúc thêm các mục của họ, các luồng chính bỏ chặn và báo cáo độ dài của danh sách. Trong trường hợp này, chúng ta có thể thấy rằng nó chứa 1.000.000 mặt hàng dự kiến. Đây sẽ là trường hợp mỗi khi mã được chạy, bất kể thay đổi trong tương lai đối với trình thông dịch tham chiếu hoặc trình thông dịch cụ thể mà mã được thực thi.queue module, such as the queue.Queue and queue.SimpleQueue classes. Chính chờ đợi các chủ đề ...queue.Queue class are designed specifically to be thread-safe in a concurrent programming environment. Kích thước danh sách: 1000000queue.Queue class.
Phát triển một lớp danh sách an toàn chủ đề mới có rủi ro.put() function. Bạn càng viết nhiều mã, bạn càng có nhiều khả năng giới thiệu các lỗi, đặc biệt là mã liên quan đến đồng thời.
Phát triển một lớp danh sách an toàn chủ đề mới có rủi ro.get() function. Bạn càng viết nhiều mã, bạn càng có nhiều khả năng giới thiệu các lỗi, đặc biệt là mã liên quan đến đồng thời.
Phát triển một lớp danh sách an toàn chủ đề mới có rủi ro. Bạn càng viết nhiều mã, bạn càng có nhiều khả năng giới thiệu các lỗi, đặc biệt là mã liên quan đến đồng thời.queue module and classes. Một giải pháp thay thế để phát triển một danh sách an toàn chủ đề là sử dụng cấu trúc dữ liệu hàng đợi. Python cung cấp các cấu trúc dữ liệu hàng đợi an toàn chủ đề trong mô-đun hàng đợi, chẳng hạn như các lớp hàng đợi.queue và hàng đợi.simplequeue.put() does not use an internal mutex lock. Các lớp này, chẳng hạn như lớp hàng đợi.queue được thiết kế đặc biệt để an toàn cho luồng trong môi trường lập trình đồng thời.qsize() function and checking if the queue is full via full() or empty via empty(). Ngoài ra, hàng đợi cung cấp một số khả năng chờ đợi/thông báo thông qua các luồng nội bộ. Đối tượng điều kiện, cho phép các chủ đề chờ đợi các mục từ hàng đợi cho đến khi có các mục mới hoặc chờ đặt các mục vào hàng đợi cho đến khi nó không đầy. Những điều kiện này cũng chia sẻ cùng một mutex.threading.Condition objects, allowing threads to wait on getting items from the queue until there are new items or to wait on putting items in the queue until it is not full. These conditions also share the same mutex. Các hoạt động đầu tiên có được một điều kiện sử dụng cùng một khóa mutex bên trong cũng được bảo vệ. Một ví dụ là nhận các mục từ hàng đợi thông qua get ().get(). Tôi khuyên bạn nên sử dụng một lớp hàng đợi thay vì phát triển lớp danh sách an toàn luồng, nếu nó cung cấp tất cả hoặc hầu hết các chức năng bạn yêu cầu trong ứng dụng của mình. Ví dụ về việc sử dụng hàng đợi an toàn chủ đềChúng tôi có thể cập nhật ví dụ danh sách an toàn chủ đề của mình để sử dụng hàng đợi.queue thay vì lớp ThreadSafelist của chúng tôi.queue.Queue instead of our ThreadSafeList class. Đầu tiên, chúng tôi phải cập nhật hàm add_items () của chúng tôi để gọi put () để thêm các mục trên hàng đợi.add_items() function to call put() to add items on the queue. Phiên bản cập nhật của chức năng được liệt kê dưới đây.
Sau đó, chúng ta có thể xác định biến an toàn của chúng ta là một ví dụ của hàng đợi.queue.queue.Queue.
Cuối cùng, khi kiểm tra kích thước của cấu trúc ở cuối chương trình, chúng ta có thể gọi hàm qsize () trên hàng đợi.qsize() function on the queue.
# Báo cáo số lượng mục trong danh sách
# Báo cáo số lượng mục trong danh sách in (kích thước f'list: {an toàn_list.qsize ()} ') 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ề danh sách an toàn chủ đề thông qua hàng đợi từ luồng nhập luồngqueue.Queue does not block when adding items – which is the majority of the work performed by the threads in this example.
# Bắt đầu chủ đềInthreads forthreads: # Đợi tất cả các luồng chấm dứt
Chạy ví dụ đầu tiên tạo ra một thể hiện của hàng đợi.
Các luồng chính chặn cho đến khi các luồng công nhân chấm dứt.
'Main Chờ đợi trước ...Kích thước danh sách: 1000000 Đọc thêm Phần này cung cấp các tài nguyên bổ sung mà bạn có thể thấy hữu ích. Nhiều chủ đề có thể nối vào một danh sách trong Python không?Chúng ta có thể nối một cách an toàn vào một tệp từ nhiều luồng bằng khóa loại trừ lẫn nhau.Python cung cấp một khóa loại trừ lẫn nhau, còn được gọi là mutex, thông qua luồng.LỚP LỚN.Đầu tiên, chúng ta có thể tạo một thể hiện của khóa để được chia sẻ bởi tất cả các luồng.. Python provides a mutual exclusion lock, also called a mutex, via the threading. Lock class. First, we can create an instance of the lock to be shared by all threads.
Đang nối vào một luồng danh sáchMặc dù danh sách trong đa luồng là không an toàn, nhưng nó an toàn theo luồng theo hoạt động của phụ lục.it is thread-safe under the operation of append .
Là chủ đề danh sáchTạo một danh sách trống.Nó thực hiện giao diện danh sách.Nó là một biến thể an toàn chủ đề của ArrayList.T đại diện cho chung chung.It is a thread-safe variant of ArrayList. T represents generic.
Là chủ đề python dictHoạt động trên Dict là an toàn cho luồng.Gil ngăn chặn nhiều hơn một trạng thái cập nhật chủ đề trong trình thông dịch Python.. The GIL prevents more than one thread updating state in the Python interpreter. |