Hướng dẫn python thread-safe counter - bộ đếm an toàn chuỗi trăn

Bạn có thể tạo một bộ đếm an toàn bằng cách sử dụng khóa mutex thông qua lớp Threading.lock.counter thread-safe by using a 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 bộ đếm an toàn chủ đề.

Bắt đầu nào.

  • Cần một bộ đếm an toàn chủ đề
  • Cách tạo bộ đếm an toàn chủ đề
  • Ví dụ về bộ đếm chủ đề không an toàn
  • Ví dụ về bộ đếm 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.threading.Thread class.

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

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

Trong lập trình đồng thời, chúng ta thường cần cập nhật một bộ đếm từ nhiều luồng.

Điều này có thể là vì nhiều lý do, chẳng hạn như:

  • Đếm các nhiệm vụ hoàn thành bởi nhiều chủ đề công nhân.
  • Đối chiếu các giá trị từ các nguồn dữ liệu khác nhau.
  • Đếm sự xuất hiện của các sự kiện.

Cập nhật một biến số từ nhiều luồng không an toàn và có thể dẫn đến một điều kiện cuộc đua.

Bạn có thể tìm hiểu thêm về điều kiện cuộc đua ở đây:

  • Điều kiện cuộc đua với một biến được chia sẻ trong Python

Làm thế nào chúng ta có thể tạo một bộ đếm an toàn chủ đề?

Cách tạo bộ đếm an toàn chủ đề

Ví dụ về bộ đếm chủ đề không an toànthreading.Lock class.

Ví dụ về bộ đếm 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.

lock=Lock()=Lock()

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.acquire() function before accessing the counter variable and calling release() after work with the counter variable has completed.

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

lock.acquire().acquire()

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.

counter+=1+=1

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

lock.release().release()

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.threading.Lock is to use the context manager which will release the lock automatically once the block is exited.

Đọ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.lock:

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.

counter+=1+=1

Đô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:

Chủ đề trong Python: Hướng dẫn hoàn chỉnh
Download my FREE PDF cheat sheet

Ví dụ về bộ đếm chủ đề không an toàn

Ví dụ về bộ đếm an toàn chủ đề

Đọc thêm

TakeawaysThreadUnsafeCounter.

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

classThreadUnsafeCounter():ThreadUnsafeCounter():

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

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

    self._counter=0self._counter=0

Trong lập trình đồng thời, chúng ta thường cần cập nhật một bộ đếm từ nhiều luồng.increment().

Điều này có thể là vì nhiều lý do, chẳng hạn như:

Đếm các nhiệm vụ hoàn thành bởi nhiều chủ đề công nhân.increment(self):

    self._counter+=1self._counter+=1

Đối chiếu các giá trị từ các nguồn dữ liệu khác nhau.

Đếm sự xuất hiện của các sự kiện.

Cập nhật một biến số từ nhiều luồng không an toàn và có thể dẫn đến một điều kiện cuộc đua.value(self):

    returnself._counterreturnself._counter

Bạn có thể tìm hiểu thêm về điều kiện cuộc đua ở đây:ThreadUnsafeCounter class is listed below.

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

classThreadUnsafeCounter():ThreadUnsafeCounter():

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

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

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

        self._counter=0self._counter =0

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

Chủ đề trong Python: Hướng dẫn hoàn chỉnhdef increment(self):

        self._counter+=1self._counter+=1

Trong lập trình đồng thời, chúng ta thường cần cập nhật một bộ đếm từ nhiều luồng.# get the counter value

Điều này có thể là vì nhiều lý do, chẳng hạn như:def value(self):

        returnself._counterreturnself._counter

Đếm các nhiệm vụ hoàn thành bởi nhiều chủ đề công nhân.

Đối chiếu các giá trị từ các nguồn dữ liệu khác nhau.

Đếm sự xuất hiện của các sự kiện.

Cập nhật một biến số từ nhiều luồng không an toàn và có thể dẫn đến một điều kiện cuộc đua.task(counter):

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

    for_inrange(100000):for_inrange(100000):

        counter.increment()counter.increment()

Chủ đề trong Python: Hướng dẫn hoàn chỉnhThreadUnsafeCounter to be shared among all threads.

.....

# Tạo bộ đếm

counter=ThreadUnsafeCounter()=ThreadUnsafeCounter()

Sau đó, chúng ta có thể tạo 10 luồng sẽ được cấu hình để gọi hàm Task () này và chuyển thể hiện bộ đếm dưới dạng đối số.task() function and pass the counter instance as an argument.

.....

# Tạo 10 luồng để tăng bộ đếm

threads=[Thread(target=task,args=(counter,))for_inrange(10)]=[Thread(target=task,args=(counter,))for_ inrange(10)]

Tiếp theo, chúng ta có thể bắt đầu tất cả mười chủ đề và sau đó đợi chúng kết thúc.

.....

# Bắt đầu tất cả các luồng

Inthreads forthreads:thread inthreads:

    thread.start()thread.start()

# Đợi tất cả các chủ đề kết thúc

Inthreads forthreads:thread in threads:

    thread.join()thread.join()

# Đợi tất cả các chủ đề kết thúc

.....

Cuối cùng, chúng ta có thể báo cáo giá trị cuối cùng của bộ đếm.

print(counter.value())(counter.value())

# Báo cáo giá trị của bộ đếm

Với mười luồng, mỗi luồng tăng 100.000 lần, chúng tôi hy vọng giá trị cuối cùng của bộ đếm là 1.000.000.

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

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ề một bộ đếm không an toàn (có điều kiện chủng tộc)threading import Thread

từ luồng nhập luồng

classThreadUnsafeCounter():ThreadUnsafeCounter():

# Chủ đề lớp quầy không an toàn# constructor

& nbsp; & nbsp; & nbsp; & nbsp;# Constructordef __init__(self):

& nbsp; & nbsp; & nbsp; & nbsp; def __init __ (self):# initialize counter

        self._counter=0self._counter=0

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# khởi tạo bộ đếm# increment the counter

& nbsp; & nbsp; & nbsp; & nbsp;# tăng bộ đếmdef increment(self):

        self._counter+=1self._counter+=1

& nbsp; & nbsp; & nbsp; & nbsp; def tăng (self):# get the counter value

& nbsp; & nbsp; & nbsp; & nbsp;# Nhận giá trị bộ đếmdef value(self):

        returnself._counterreturn self._counter

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

# Nhiệm vụ được thực hiện bởi các chủ đềtask(counter):

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# khởi tạo bộ đếm# increment the counter

    for_inrange(100000):for_inrange(100000):

        counter.increment()counter.increment()

# Tạo bộ đếm

counter=ThreadUnsafeCounter()=ThreadUnsafeCounter()

# Tạo 10 luồng để tăng bộ đếm

threads=[Thread(target=task,args=(counter,))for_inrange(10)]= [Thread(target=task,args=(counter,))for_inrange(10)]

# Bắt đầu tất cả các luồng

Inthreads forthreads:thread inthreads:

    thread.start()thread.start()

# Đợi tất cả các chủ đề kết thúc

Inthreads forthreads:thread inthreads:

    thread.join()thread.join()

Cuối cùng, chúng ta có thể báo cáo giá trị cuối cùng của bộ đếm.

print(counter.value())(counter.value())

# Báo cáo giá trị của bộ đếmThreadUnsafeCounter class.

Với mười luồng, mỗi luồng tăng 100.000 lần, chúng tôi hy vọng giá trị cuối cùng của bộ đếm là 1.000.000.

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ề một bộ đếm không an toàn (có điều kiện chủng tộc)

từ luồng nhập luồng_counter variable is updated in a thread unsafe manner.

# Chủ đề lớp quầy không an toàn

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

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

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp;# khởi tạo bộ đếm


& nbsp; & nbsp; & nbsp; & nbsp;# tăng bộ đếm

& nbsp; & nbsp; & nbsp; & nbsp; def tăng (self):

& nbsp; & nbsp; & nbsp; & nbsp;# Nhận giá trị bộ đếm

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


# Nhiệm vụ được thực hiện bởi các chủ đề

Nhiệm vụ def (Counter):ThreadUnsafeCounter class that we developed in the previous section can be updated to be thread-safe.

Chạy ví dụ đầu tiên tạo ra một thể hiện của lớp ThreadunSafeC gặp gỡ của chúng tôi.threading.Lock instance to the class to protect the counter variable.

Tiếp theo, chúng tôi tạo và định cấu hình mười chủ đề mà tất cả đều cố gắng tăng bộ đếm 100.000 lần. Các luồng sau đó được bắt đầu và các khối chủ đề chính cho đến khi tất cả các luồng mới kết thúc.

Cuối cùng, giá trị của bộ đếm được báo cáo.

Trong trường hợp này, chúng ta có thể thấy rằng bộ đếm không có giá trị mong đợi. Thay vào đó, nó là khoảng 280.000 so với giá trị 1.000.000 mà chúng tôi mong đợi.__init__(self):

Trong thực tế, mỗi khi chương trình được chạy, bạn sẽ thấy một giá trị khác nhau.# initialize counter

    self._counter=0self._counter=0

Điều này là do biến _Count được cập nhật theo cách không an toàn.# initialize lock

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

Có một điều kiện cuộc đua.increment() method, we can first acquire the lock then change the value using the context manager.

Bạn có thể tìm hiểu thêm về loại điều kiện cuộc đua này ở đây:

Điều kiện cuộc đua với một biến được chia sẻ trong Pythonincrement(self):

Tiếp theo, hãy để cập nhật lớp học của chúng tôi để an toàn chủ đề.with self._lock:

        self._counter+=1self._counter+=1

Khóa học luồng python miễn phívalue() method, we can again protect the counter variable by first acquiring the lock.

Đăng ký khóa học email 7 ngày miễn phí của tôi và khám phá cách sử dụng mô-đun luồng Python, bao gồm cách tạo và bắt đầu các chủ đề mới, cách sử dụng Mutex và Semaphore, và nhiều hơn nữa!

Nhấp vào nút bên dưới và nhập địa chỉ email của bạn để đăng ký và nhận bài học đầu tiên ngay bây giờ.value(self):

Tiếp theo, hãy để cập nhật lớp học của chúng tôi để an toàn chủ đề.with self._lock:

        returnself._counterreturnself._counter

Khóa học luồng python miễn phíThreadSafeCounter. The updated thread-safe version of the class is listed below.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

Đăng ký khóa học email 7 ngày miễn phí của tôi và khám phá cách sử dụng mô-đun luồng Python, bao gồm cách tạo và bắt đầu các chủ đề mới, cách sử dụng Mutex và Semaphore, và nhiều hơn nữa!

classThreadSafeCounter():ThreadSafeCounter():

& 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 bộ đếm# initialize counter

        self._counter=0self._counter =0

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

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

& nbsp; & nbsp; & nbsp; & nbsp;# tăng bộ đếm# increment the counter

& nbsp; & nbsp; & nbsp; & nbsp; def tăng (self):def increment(self):

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

            self._counter+=1self._counter+=1

& nbsp; & nbsp; & nbsp; & nbsp;# Nhận giá trị bộ đếm# get the counter value

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

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

            returnself._counterreturnself._counter

& nbsp; & nbsp; & nbsp; & nbsp;# Nhận giá trị bộ đếm

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

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

Và đó là nó.

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ề bộ đếm an toàn chủ đềthreading import Lock

từ luồng nhập luồng

classThreadSafeCounter():ThreadSafeCounter():

& 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 bộ đếm# initialize counter

        self._counter=0self._counter=0

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

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

& nbsp; & nbsp; & nbsp; & nbsp;# tăng bộ đếm# increment the counter

& nbsp; & nbsp; & nbsp; & nbsp; def tăng (self):def increment(self):

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

            self._counter+=1self._counter+=1

& nbsp; & nbsp; & nbsp; & nbsp;# Nhận giá trị bộ đếm# get the counter value

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

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

            returnself._counterreturnself._counter

& nbsp; & nbsp; & nbsp; & nbsp;# Nhận giá trị bộ đếm

& nbsp; & nbsp; & nbsp; & nbsp; def value (self):task(counter):

& nbsp; & nbsp; & nbsp; & nbsp;# tăng bộ đếm# increment the counter

    for_inrange(100000):for _inrange(100000):

        counter.increment()counter.increment()

& nbsp; & nbsp; & nbsp; & nbsp; def tăng (self):

counter=ThreadSafeCounter()=ThreadSafeCounter()

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

threads=[Thread(target=task,args=(counter,))for_inrange(10)]=[Thread(target=task,args=(counter,))for_inrange(10)]

& nbsp; & nbsp; & nbsp; & nbsp;# Nhận giá trị bộ đếm

& nbsp; & nbsp; & nbsp; & nbsp; def value (self):thread inthreads:

    thread.start()thread.start()

Và đó là nó.

& nbsp; & nbsp; & nbsp; & nbsp; def value (self):thread inthreads:

    thread.join()thread.join()

Và đó là nó.

print(counter.value())(counter.value())

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ề bộ đếm an toàn chủ đề

từ luồng nhập luồng

từ khóa nhập khẩu ren

# Chủ đề lớp quầy an toàn

# Nhiệm vụ được thực hiện bởi các chủ đề

  • Nhiệm vụ def (Counter):
  • # Tạo bộ đếm
  • # Tạo 10 luồng để tăng bộ đếm
  • # Bắt đầu tất cả các luồng
  • Inthreads forthreads:

# Đợi tất cả các chủ đề kết thúc

# Báo cáo giá trị của bộ đếm

Chạy ví dụ đầu tiên tạo ra trường hợp truy cập được chia sẻ trước đó.
Ask your questions in the comments below and I will do my best to answer.

Sau đó, tạo và bắt đầu mười luồng, mỗi chủ đề đang cố gắng tăng bộ đếm 100.000 lần mỗi lần.