“This is the third day of my participation in the First Challenge 2022, for more details: First Challenge 2022”.

Official Python column # 51, stop! Don’t miss this zero-based article!

The Semaphore Semaphore and a simple realization of current limiter are presented.

The code works and looks error-free.

However, careful readers will notice that if we appear like the following semaphore usage:

Xuewei_semaphore. Acquire () # xuewei_semaphore //do something.... Xuewei_semaphore. Release () #>>> xuewei_semaphore. Release () #>> xuewei_semaphore. Release () #>> xuewei_semaphore.Copy the code

Semaphore is doing a little bit more releasing than getting. Is that a problem?

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# @time: 2021/11/27 10:43 PM
# @Author : LeiXueWei
# @csDN /Juejin/Wechat: Lei Xuewei
# @XueWeiTag: CodingDemo
# @File : thread_semaphore_boundvs_unbound.py
# @Project : hello
import threading
import time

xuewei_semaphore = threading.Semaphore(1) A bounded semaphore

print("xuewei_semaphore:", xuewei_semaphore)


def run() :
    print(" %s ready" % threading.current_thread().name)
    xuewei_semaphore.acquire()
    print(" %s go" % threading.current_thread().name)
    time.sleep(0.1)
    print(" %s completed" % threading.current_thread().name)
    xuewei_semaphore.release()


def abnormal_run() :
    run()
    xuewei_semaphore.release()  # too many releases


t = threading.Thread(name="Normal use semaphore", target=run)
t.start()
time.sleep(1)
t = threading.Thread(name="Abnormal use semaphore", target=abnormal_run)
t.start()
Copy the code

The above study committee combined with the first sharing semaphore article, simplified, focusing on the effects of multiple release semaphore.

We found that the program did not report any errors:

What if we added calls to abnormal uses, such as the following code:

# Add the following code after the above code
for i in range(10000):
    t = threading.Thread(name="Abnormal use semaphore"+str(i), target=abnormal_run)
    t.start()
Copy the code

No error reported throughout!!

I was shocked! Python is too fault-tolerant (this is high eq, 😂)

The bounded semaphore comes along and fills the hole

Threading. BoundedSemaphore this class is bounded semaphore, English name is intuitive.

What is bounded?

Hold the line like a human being. So where does Semaphore draw the line? We can click on this class to see some of the code.

Semaphore maintains a _value. A bounded Semaphore simply adds a variable _initial_value to record the initial Semaphore value.

Later, when we call release, the bounded semaphore checks each time to see if _value is out of bounds (that is, if _initial_value is exceeded, ValueError is raised to indicate that _value is out of bounds!).

This is too friendly.

Let’s use bounded semaphores to show that, in contrast to the first code, we just put

xuewei_semaphore = threading.Semaphore(1)

To:

xuewei_semaphore = threading.BoundedSemaphore(1)

So readers can directly change, of course, can also choose to directly copy the following code and save a file to run.

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# @time: 2021/11/27 10:43 PM
# @Author : LeiXueWei
# @csDN /Juejin/Wechat: Lei Xuewei
# @XueWeiTag: CodingDemo
# @File : thread_semaphore_boundvs_unbound3.py
# @Project : hello
import threading
import time

xuewei_semaphore = threading.BoundedSemaphore(1)

print("xuewei_semaphore:", xuewei_semaphore)


def run() :
    print(" %s ready" % threading.current_thread().name)
    xuewei_semaphore.acquire()
    print(" %s go" % threading.current_thread().name)
    time.sleep(0.1)
    print(" %s completed" % threading.current_thread().name)
    xuewei_semaphore.release()


def abnormal_run() :
    run()
    xuewei_semaphore.release()  # too many releases


t = threading.Thread(name="Normal use semaphore", target=run)
t.start()
time.sleep(1)
t = threading.Thread(name="Abnormal use semaphore", target=abnormal_run)
t.start()
Copy the code

After using bounded, sure enough, excessive release, the system reported an error! I’m relieved.

conclusion

You should try to use bounded semaphores, they help us hold the boundary. It’s not going to let our program continue to work just because we accidentally made a mistake and wrote one more release. (Probably stay up late writing code, don’t! Writing code requires a comfortable state, higher quality)

If you are using pure Semaphore, make sure that it is wrapped (enclosed for calls) and not open to use of acquire and Release before you can install it.

For those who like Python, please check out the Python Basics section or the Python Getting Started to Master Section

Continuous learning and continuous development, I am Lei Xuewei! Programming is fun. The key is to get the technology right. Welcome to wechat, like support collection!