Hướng dẫn python multithreading on a list - python đa luồng trên một danh sách

Bạn có thể tạo một danh sách an toàn chủ đề bằng cách sử dụng khóa loại trừ lẫn nhau (MUTEX) thông qua lớp Threading.lock. thread-safe list by using a mutual exclusion (mutex) lock via the threading.Lock class.

Trong hướng dẫn này, bạn sẽ khám phá cách phát triển một danh sách an toàn chủ đề trong Python.

Bắt đầu nào.

  • Cần một danh sách an toàn chủ đề
  • Hầu hết các hoạt động danh sách là nguyên tử
  • Hoạt động danh sách nguyên tử rất dễ vỡ
  • Cách phát triển danh sách an toàn chủ đề
  • Ví dụ về danh sách an toàn chủ đề
  • Thay thế cho một danh sách an toàn chủ đề
  • Ví dụ về việc sử dụng hàng đợi an toàn chủ đề
  • Đọc thêm
  • Takeaways

Cần một danh sách an toàn chủ đề

Hầu hết các hoạt động danh sách là nguyên tử

Hoạt động danh sách nguyên tử rất dễ vỡ

Cách phát triển danh sách an toàn chủ đề

Ví dụ về danh sách an toàn chủ đềthreading.Thread class.

Thay thế cho một danh sách an toàn chủ đề

  • Ví dụ về việc sử dụng hàng đợi an toàn chủ đề

Đọc thêm

Takeaways

Một chủ đề là một chủ đề thực thi trong một chương trình máy tính.

Hầu hết các hoạt động danh sách là nguyên tử

Hoạt động danh sách nguyên tử rất dễ vỡ

Cách phát triển danh sách an toàn chủ đềList class.

Ví dụ về danh sách an toàn chủ đề

Thay thế cho một danh sách an toàn chủ đề

Ví dụ về việc sử dụng hàng đợi an toàn chủ đề

Đọc thêm

Specifically:

  • Takeawaysappend().
  • Một chủ đề là một chủ đề thực thi trong một chương trình máy tính.extend().
  • Mỗi chương trình Python có ít nhất một luồng thực thi được gọi là luồng chính. Cả hai quy trình và luồng được tạo và quản lý bởi hệ điều hành cơ bản.
  • Đôi khi chúng ta có thể cần tạo các luồng bổ sung trong chương trình của chúng tôi để thực thi mã đồng thời.[].
  • Python cung cấp khả năng tạo và quản lý các luồng mới thông qua mô -đun luồng và lớp luồng.pop().
  • Bạn có thể tìm hiểu thêm về các chủ đề Python trong hướng dẫn:sort().

Chủ đề trong Python: Hướng dẫn hoàn chỉnh

  • 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?

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.
Download my FREE PDF cheat sheet

Hoạt động danh sách nguyên tử rất dễ vỡ

Cách phát triển danh sách an toàn chủ đề

Ví dụ về danh sách an toàn chủ đề

  • Thay thế cho một danh sách an toàn chủ đề
  • Ví dụ về việc sử dụng hàng đợi an toàn chủ đề
  • Đọc thêm

Takeaways

Một chủ đề là một chủ đề thực thi trong một chương trình máy tính.

Mỗi chương trình Python có ít nhất một luồng thực thi được gọi là luồng chính. Cả hai quy trình và luồng được tạo và quản lý bởi hệ điều hành cơ bản.

Đôi khi chúng ta có thể cần tạo các luồng bổ sung trong chương trình của chúng tôi để thực thi mã đồng thời.

Python cung cấp khả năng tạo và quản lý các luồng mới thông qua mô -đun luồng và lớp luồng.

Bạn có thể tìm hiểu thêm về các chủ đề Python trong hướng dẫn:

Đọc thêm

Takeaways


Một chủ đề là một chủ đề thực thi trong một chương trình máy tính.

Mỗi chương trình Python có ít nhất một luồng thực thi được gọi là luồng chính. Cả hai quy trình và luồng được tạo và quản lý bởi hệ điều hành cơ bản.

Đôi khi chúng ta có thể cần tạo các luồng bổ sung trong chương trình của chúng tôi để thực thi mã đồng thời.

Python cung cấp khả năng tạo và quản lý các luồng mới thông qua mô -đun luồng và lớp luồng.
 


Cách phát triển danh sách an toàn chủ đề

Ví dụ về danh sách an toàn chủ đề

Thay thế cho một danh sách an toàn chủ đề

Ví dụ về việc sử dụng hàng đợi an toàn chủ đề

Một thể hiện của luồng.lock có thể được sử dụng để bảo vệ danh sách.threading.Lock can be used to protect the list.

Bạn có thể tìm hiểu thêm về khóa Mutex ở đây:

  • Cách sử dụng khóa mutex trong Python

Khóa này phải được mua trước khi hoạt động trong danh sách và được phát hành khi hoạt động trong danh sách đã hoàn thành.

Ví dụ:

.....

# có được khóa

lock.acquire().acquire()

# hoạt động trong danh sách

.....

# có được khóa

lock.release().release()

# hoạt động trong danh sách

# Phát hành khóa

Ví dụ:

.....

# có được khóa

# hoạt động trong danh sáchlock:

# hoạt động trong danh sách

.....

# có được khóa

# hoạt động trong danh sách

# Phát hành khóathreading.RLock class. It will allow the lock to be acquired by the same thread again.

Điều này đảm bảo rằng chỉ có một luồng tại một thời điểm có thể hoạt động trong danh sách.

  • Giao diện Trình quản lý bối cảnh trên khóa có thể được sử dụng để đơn giản hóa thao tác này, cho phép khóa được giải phóng tự động.

với khóa:

Điều này thêm chi phí, làm cho mỗi hoạt động danh sách chậm hơn nhiều so với nếu không có khóa. Lợi ích là niềm tin rằng các điều kiện chủng tộc với danh sách đã được loại bỏ hoàn toàn.List class and implement thread-safe versions of all or a subset of functions.

Nếu thiết kế của bạn là có một số chức năng được bọc, hãy gọi các chức năng được bọc khác, thì khóa reentrant được ưa thích, để tránh bế tắc.List class, except the functions on the class are threads-safe.

Đ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.List class.

Bạn có thể tìm hiểu thêm về khóa reentrant ở đây:List that is thread safe, it is a data structure designed for a thread-safe use case that must be treated with extreme care.

Cách sử dụng khóa Reentrant trong PythonThreadSafeList.

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.

classThreadSafeList():ThreadSafeList():

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.

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.

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.

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.__init__(self):

Đầu tiên, chúng ta có thể xác định lớp với một tên rõ ràng như ThreadSafelist.# initialize the list

    self._list=list()self._list=list()

# lớp tùy chỉnh gói danh sách để làm cho nó an toàn# initialize the lock

    self._lock=Lock()self._lock =Lock()

# ...

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.

  • # người xây dựngappend().
  • def __init __ (tự):pop().
  • & nbsp; & nbsp; & nbsp; & nbsp;# khởi tạo danh sáchget().
  • & nbsp; & nbsp; & nbsp; & nbsp;# khởi tạo khóalength().

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:

Thêm một giá trị thông qua append ().

Xóa và trả về một giá trị thông qua pop ().

Truy cập một giá trị tại một chỉ mục thông qua get ().append(self,value):

Nhận độ dài của danh sách thông qua độ dài ().# acquire the lock

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.with self._lock:

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.# append the value

        self._list.append(value)self._list.append(value)

Ví dụ: phương pháp cho hoạt động phụ lục được liệt kê dưới đây.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

# Thêm giá trị vào danh sách

def expend (tự, giá trị):pop(self):

Nhận độ dài của danh sách thông qua độ dài ().# acquire the lock

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.with self._lock:

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.# pop a value from the list

        returnself._list.pop()return self._list.pop()

Ví dụ: phương pháp cho hoạt động phụ lục được liệt kê dưới đây.

# Thêm giá trị vào danh sáchget(self,index):

Nhận độ dài của danh sách thông qua độ dài ().# acquire the lock

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.with self._lock:

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.# read a value at the index

        returnself._list[index]returnself._list[index]

Ví dụ: phương pháp cho hoạt động phụ lục được liệt kê dưới đây.

# Thêm giá trị vào danh sáchlength(self):

Nhận độ dài của danh sách thông qua độ dài ().# acquire the lock

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.with self._lock:

        returnlen(self._list)returnlen(self._list)

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.

# Thêm giá trị vào danh sách

def expend (tự, giá trị):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

# lớp tùy chỉnh gói danh sách để làm cho nó an toàn

classThreadSafeList():ThreadSafeList():

& nbsp; & nbsp; & nbsp; & nbsp;# Constructor# constructor

& nbsp; & nbsp; & nbsp; & nbsp; def __init __ (self):def __init__(self):

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# khởi tạo danh sách# initialize the list

        self._list=list()self._list=list()

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# khởi tạo khóa# initialize the lock

        self._lock=Lock()self._lock= Lock()

& nbsp; & nbsp; & nbsp; & nbsp;# thêm một giá trị vào danh sách# add a value to the list

& nbsp; & nbsp; & nbsp; & nbsp; def append (self, value):def append(self,value):

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# acquire the lock

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;with self._lock:

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# append the value

            self._list.append(value)self._list.append(value)

& nbsp; & nbsp; & nbsp; & nbsp;# xóa và trả về giá trị cuối cùng từ danh sách# remove and return the last value from the list

& nbsp; & nbsp; & nbsp; & nbsp; def pop (self):def pop(self):

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# acquire the lock

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;with self._lock:

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# pop a value from the list

            returnself._list.pop()returnself._list.pop()

& nbsp; & nbsp; & nbsp; & nbsp;# xóa và trả về giá trị cuối cùng từ danh sách# read a value from the list at an index

& nbsp; & nbsp; & nbsp; & nbsp; def pop (self):def get(self, index):

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# acquire the lock

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;with self._lock:

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# read a value at the index

            returnself._list[index]return self._list[index]

& nbsp; & nbsp; & nbsp; & nbsp;# xóa và trả về giá trị cuối cùng từ danh sách# return the number of items in the list

& nbsp; & nbsp; & nbsp; & nbsp; def pop (self):def length(self):

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# acquire the lock

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;with self._lock:

            returnlen(self._list)returnlen(self._list)

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;sort() and extend().

& nbsp; & nbsp; & nbsp; & nbsp;# xóa và trả về giá trị cuối cùng từ danh sáchindex() or reverse().

& nbsp; & nbsp; & nbsp; & nbsp; def pop (self):

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;

& nbsp; & nbsp; & nbsp; & nbsp;# đọc một giá trị từ danh sách tại một chỉ mục

& 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):ThreadSafeList, then loop 100,000 times, adding a value to the list each iteration.

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 ().add_items() function below implements this.

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 trình diễn an toàn chủ đề của danh sách trong một ví dụ đã làm việc.add_items(safe_list):

    foriinrange(100000):foriinrange(100000):

        safe_list.append(i)safe_list.append(i)

Ví dụ về danh sách an toàn chủ đề

Chúng ta có thể phát triển một ví dụ về việc sử dụng danh sách an toàn luồng từ nhiều luồng...

Trong ví dụ này, chúng tôi sẽ tạo mười luồng và mỗi chủ đề cố gắng thêm 100.000 mục vào danh sách đồng thời. Kết quả dự kiến ​​sẽ là một danh sách với 1.000.000 mặt hàng.

safe_list=ThreadSafeList()=ThreadSafeList()

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.add_items() function and be passed the same ThreadSafeList as an argument.

Đầu tiên, chúng ta có thể xác định một chức năng được thực thi bởi mỗi luồng công nhân.

Chúng ta có thể phát triển một ví dụ về việc sử dụng danh sách an toàn luồng từ nhiều luồng...

Trong ví dụ này, chúng tôi sẽ tạo mười luồng và mỗi chủ đề cố gắng thêm 100.000 mục vào danh sách đồng thời. Kết quả dự kiến ​​sẽ là một danh sách với 1.000.000 mặt hàng.

threads=[Thread(target=add_items,args=(safe_list,))foriinrange(10)]=[Thread(target=add_items,args=(safe_list,))fori inrange(10)]

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.

Chúng ta có thể phát triển một ví dụ về việc sử dụng danh sách an toàn luồng từ nhiều luồng...

Trong ví dụ này, chúng tôi sẽ tạo mười luồng và mỗi chủ đề cố gắng thêm 100.000 mục vào danh sách đồng thời. Kết quả dự kiến ​​sẽ là một danh sách với 1.000.000 mặt hàng.

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.thread inthreads:

    thread.start()thread.start()

Đầu tiên, chúng ta có thể xác định một chức năng được thực thi bởi mỗi luồng công nhân.

Chúng ta có thể phát triển một ví dụ về việc sử dụng danh sách an toàn luồng từ nhiều luồng...

Trong ví dụ này, chúng tôi sẽ tạo mười luồng và mỗi chủ đề cố gắng thêm 100.000 mục vào danh sách đồng thời. Kết quả dự kiến ​​sẽ là một danh sách với 1.000.000 mặt hàng.

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.('Main waiting for threads...')

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.thread inthreads:

    thread.join()thread.join()

Đầu tiên, chúng ta có thể xác định một chức năng được thực thi bởi mỗi luồng công nhân.

Chúng ta có thể phát triển một ví dụ về việc sử dụng danh sách an toàn luồng từ nhiều luồng...

Trong ví dụ này, chúng tôi sẽ tạo mười luồng và mỗi chủ đề cố gắng thêm 100.000 mục vào danh sách đồng thời. Kết quả dự kiến ​​sẽ là một danh sách với 1.000.000 mặt hàng.

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.(f'List size: {safe_list.length()}')

Đầu tiên, chúng ta có thể xác định một chức năng được thực thi bởi mỗi luồng công nhân.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

# SuperfastPython.com

# Ví dụ về danh sách an toàn chủ đề

từ luồng nhập luồngthreading import Thread

từ khóa nhập khẩu renthreading import Lock

# lớp tùy chỉnh gói danh sách để làm cho nó an toàn

classThreadSafeList():ThreadSafeList():

& nbsp; & nbsp; & nbsp; & nbsp;# Constructor# constructor

& nbsp; & nbsp; & nbsp; & nbsp; def __init __ (self):def __init__(self):

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# khởi tạo danh sách# initialize the list

        self._list=list()self._list=list()

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# khởi tạo khóa# initialize the lock

        self._lock=Lock()self._lock=Lock()

& nbsp; & nbsp; & nbsp; & nbsp;# thêm một giá trị vào danh sách# add a value to the list

& nbsp; & nbsp; & nbsp; & nbsp; def append (self, value):def append(self,value):

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# acquire the lock

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;with self._lock:

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# append the value

            self._list.append(value)self._list.append(value)

& nbsp; & nbsp; & nbsp; & nbsp;# xóa và trả về giá trị cuối cùng từ danh sách# remove and return the last value from the list

& nbsp; & nbsp; & nbsp; & nbsp; def pop (self):def pop(self):

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# acquire the lock

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;with self._lock:

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# pop a value from the list

            returnself._list.pop()returnself._list.pop()

& nbsp; & nbsp; & nbsp; & nbsp;# xóa và trả về giá trị cuối cùng từ danh sách# read a value from the list at an index

& nbsp; & nbsp; & nbsp; & nbsp; def pop (self):def get(self, index):

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# acquire the lock

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;with self._lock:

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# read a value at the index

            returnself._list[index]return self._list[index]

& nbsp; & nbsp; & nbsp; & nbsp;# xóa và trả về giá trị cuối cùng từ danh sách# return the number of items in the list

& nbsp; & nbsp; & nbsp; & nbsp; def pop (self):def length(self):

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# acquire the lock

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;with self._lock:

            returnlen(self._list)returnlen(self._list)

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;

& nbsp; & nbsp; & nbsp; & nbsp;# xóa và trả về giá trị cuối cùng từ danh sáchadd_items(safe_list):

    foriinrange(100000):for iinrange(100000):

        safe_list.append(i)safe_list.append(i)

& nbsp; & nbsp; & nbsp; & nbsp; def pop (self):

safe_list=ThreadSafeList()=ThreadSafeList()

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;

threads=[Thread(target=add_items,args=(safe_list,))foriinrange(10)]=[Thread(target=add_items,args=(safe_list,))foriin range(10)]

& nbsp; & nbsp; & nbsp; & nbsp;# đọc một giá trị từ danh sách tại một chỉ mục

& nbsp; & nbsp; & nbsp; & nbsp; def get (self, index):thread inthreads:

    thread.start()thread.start()

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;

& nbsp; & nbsp; & nbsp; & nbsp;# Trả về số lượng mục trong danh sách('Main waiting for threads...')

& nbsp; & nbsp; & nbsp; & nbsp; def get (self, index):thread inthreads:

    thread.join()thread.join()

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;

& nbsp; & nbsp; & nbsp; & nbsp;# Trả về số lượng mục trong danh sách(f'List size: {safe_list.length()}')

& nbsp; & nbsp; & nbsp; & nbsp; độ dài def (self):

# Thêm các mục vào danh sách

def add_items (an toàn_list):

# Tạo danh sách an toàn chủ đề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.

# Định cấu hình các luồng để thêm vào danh sách

# Bắt đầu chủ đề

Inthreads forthreads:

# Đợ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

in (kích thước f'list: {an toàn_list.length ()} ')

Chạy ví dụ đầu tiên tạo ra một thể hiện của danh sách an toàn luồng của chúng tôi, nội bộ xác định một thể hiện danh sách mới và khóa để bảo vệ 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.queue module, such as the queue.Queue and queue.SimpleQueue classes.

Các luồng chính chặn cho đến khi tất cả mười luồng mới chấm dứt.queue.Queue class are designed specifically to be thread-safe in a concurrent programming environment.

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.queue.Queue class.

.....

# Tạo hàng đợi an toàn chủ đề

queue=queue.Queue()=queue.Queue()

Chúng ta có thể thêm các mục vào hàng đợi theo cách an toàn chủ đề bằng cách sử dụng hàm put ().put() function.

Ví dụ:

.....

# Thêm một mục vào hàng đợi theo cách an toàn cho luồng

queue.put(item).put(item)

Chúng ta có thể xóa các mục khỏi hàng đợi theo cách an toàn luồng bằng cách sử dụng hàm get ().get() function.

Ví dụ:

.....

# Thêm một mục vào hàng đợi theo cách an toàn cho luồng

item=queue.get()=queue.get()

Chúng ta có thể xóa các mục khỏi hàng đợi theo cách an toàn luồng bằng cách sử dụng hàm get ().

# Nhận mục tiếp theo từ hàng đợi theo cách an toàn chủ đềqueue module and classes.

Các lớp hàng đợi này được thiết kế để nhanh chóng, trừu tượng hóa cách cấu trúc được giữ an toàn cho chủ đề trong khi thực hiện theo cách nhanh nhất và phù hợp nhất cho phiên bản Python hiện tại.

Chúng ta có thể thấy điều này nếu chúng ta xem lại mã nguồn cho mô -đun hàng đợi và các lớp.put() does not use an internal mutex lock.

Như vậy, một số hoạt động được thực hiện trực tiếp, dựa vào bản chất nguyên tử của lớp Danh sách.qsize() function and checking if the queue is full via full() or empty via empty().

Ví dụ: đặt một mục với put () không sử dụng khóa mutex bên trong.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 khác liên quan đến tổng hợp các hoạt động trong danh sách được bảo vệ bởi khóa mutex bên trong như kiểm tra kích thước của hàng đợi thông qua hàm qsize () và kiểm tra xem hàng đợi có đầy đủ thông qua đầy đủ () hoặc trống thông qua trống ().get().

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.

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 ().

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.queue.Queue instead of our ThreadSafeList class.

Ví dụ về việc sử dụng hàng đợi an toàn chủ đềadd_items() function to call put() to add items on the queue.

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.

Đầ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.

Phiên bản cập nhật của chức năng được liệt kê dưới đây.add_items(safe_list):

    foriinrange(100000):foriinrange(100000):

        safe_list.put(i)safe_list.put(i)

# Thêm các mục vào danh sáchqueue.Queue.

.....

def add_items (an toàn_list):

safe_list=Queue()=Queue()

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.qsize() function on the queue.

.....

# Tạo danh sách an toàn chủ đề (Hàng đợi)

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.(f'List size: {safe_list.qsize()}')

# Báo cáo số lượng mục trong danh sách

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

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.comthreading import Thread

# Ví dụ về danh sách an toàn chủ đề thông qua hàng đợiqueue import Queue

Đầ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.

Phiên bản cập nhật của chức năng được liệt kê dưới đây.add_items(safe_list):

    foriinrange(100000):for iinrange(100000):

        safe_list.put(i)safe_list.put(i)

def add_items (an toàn_list):

safe_list=Queue()=Queue()

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.

threads=[Thread(target=add_items,args=(safe_list,))foriinrange(10)]=[Thread(target=add_items,args=(safe_list,))foriin range(10)]

# Tạo danh sách an toàn chủ đề (Hàng đợi)

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.thread inthreads:

    thread.start()thread.start()

# 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 ()} ')('Main waiting for threads...')

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.thread inthreads:

    thread.join()thread.join()

# Tạo danh sách an toàn chủ đề (Hàng đợi)

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.(f'List size: {safe_list.qsize()}')

# 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.

từ hàng đợi hàng đợiMain waiting forthreads...

# Định cấu hình các luồng để thêm vào danh sáchsize:1000000

# Bắt đầu chủ đề

Inthreads forthreads:

  • # Đợi tất cả các luồng chấm dứt
  • in ('Chờ các chủ đề chính ...')
  • Chạy ví dụ đầu tiên tạo ra một thể hiện của hàng đợi.
  • Mười chủ đề sau đó được cấu hình và bắt đầu. Mỗi chủ đề thêm 100.000 mục vào hàng đợi đồng thời nhanh nhất có thể.
  • Các luồng chính chặn cho đến khi các luồng công nhân chấm dứt.

Cuối cùng, các luồng chính bỏ chặn và báo cáo kích thước của hàng đợi.

Trong trường hợp này, kích thước được báo cáo là 1.000.000 mặt hàng, như mong đợi.

Hơn nữa, bạn sẽ nhận thấy rằng ví dụ này nhanh hơn đáng kể để thực thi vì hàng đợi.queue không chặn khi thêm các mục - phần lớn công việc được thực hiện bởi các luồng trong ví dụ này.
Ask your questions in the comments below and I will do my best to answer.

'Main Chờ đợi trước ...

Là danh sách trong chủ đề python

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.Many common operations on a list are atomic, meaning that they are thread-safe.

Python có thể chạy nhiều chủ đề không?

Để tóm tắt lại, luồng trong Python cho phép nhiều luồng được tạo trong một quy trình duy nhất, nhưng do Gil, không ai trong số chúng sẽ chạy cùng một lúc.Chủ đề vẫn là một lựa chọn rất tốt khi chạy nhiều tác vụ ràng buộc I/O đồng thời.threading in Python allows multiple threads to be created within a single process, but due to GIL, none of them will ever run at the exact same time. Threading is still a very good option when it comes to running multiple I/O bound tasks concurrently.

Làm cách nào để bắt đầu nhiều luồng cùng một lúc trong Python?

Để thực hiện luồng trong Python, bạn phải thực hiện ba bước: kế thừa lớp chứa chức năng bạn muốn chạy trong một luồng riêng biệt bằng cách sử dụng lớp luồng.Đặt tên cho chức năng bạn muốn thực thi trong một luồng chạy ().Gọi hàm start () từ đối tượng của lớp chứa phương thức Run ().

Python có tự động đa luồng không?

Nói chung, Python chỉ sử dụng một luồng để thực thi tập hợp các câu lệnh bằng văn bản.Điều này có nghĩa là trong Python, chỉ có một luồng sẽ được thực thi tại một thời điểm.Python only uses one thread to execute the set of written statements. This means that in python only one thread will be executed at a time.