Python thread 21 Barrier class parses again

Official Python column chapter 58, students stop, don't miss this article starting from 0!

This article continues to introduce the classes in threading library, threading Barrier class.

This class is very easy to use. Directly specify the value. By calling its wait method, you can Easily realize synchronous waiting of multiple threads.

You can also see that the school committee used it before Implementation of condition (you need to use notify and wait correctly, and add wait(timeout) to realize the waiting of ten athletes.) it's obviously a little better than the Barrier class.

Continue to look at the Barrier class

Read the construction method of the Barrier class again (as follows). We can see that it holds the Condition object and_ count, _parties.

Basically, Barrier uses these three to implement a mechanism waiting for release. Let's take a look at the wait source code.

In addition, there are other parameters like action, which will be called by a thread before the whole Barrier is release d.

def __init__(self, parties, action=None, timeout=None):
    self._cond = Condition(Lock())
    self._action = action
    self._timeout = timeout
    self._parties = parties
    self._state = 0 #0 filling, 1, draining, -1 resetting, -2 broken
    self._count = 0

The school committee has prepared the following small demo method, which readers can post in the code shared earlier.

def post_action():
    print("The athlete called barrier Method after release- %s" % threading.current_thread().name)
barrier = threading.Barrier(parties=10,action=post_action)

Rerun code can see that only a certain athlete thread (which athlete is random, see the actual project is the thread that finally called the wait method) executed post_aciton method.

The following is the effect display of an execution:

The point is this wait method

Like Condition, it also supports timeout (that is, the number of threads is not enough, and the code behind wait is enforced after a fixed wait delay).

def wait(self, timeout=None):
   if timeout is None:
       timeout = self._timeout
   with self._cond:
       self._enter() # Block while the barrier drains.
       index = self._count
       self._count += 1
       try:
           if index + 1 == self._parties:
               # We release the barrier
               self._release()
           else:
               # We wait until someone releases us
               self._wait(timeout)
           return index
       finally:
           self._count -= 1
           # Wake up any threads waiting for barrier to drain.
           self._exit()

This code is also very intuitive. Each thread calls the wait method once, which is held by the Barrier object_ count is incremented by 1 (starting from 0).

Yes_ count is_ When parties-1, Barrier calls_ release releases the lock held internally.

OK, keep looking_ The release function is simpler. The key point is: self_ cond. notify_ All (), this sentence is executed.

It calls notify_all function, which releases the condition of other calls Wait method.

This is the internal implementation of the Barrier class.

def _release(self):
    try:
        if self._action:
            self._action()
        # enter draining state
        self._state = 1
        self._cond.notify_all()
    except:
        #an exception during the _action handler.  Break and reraise
        self._break()
        raise

In addition, here we also see_ The action method was called, which also verified the demo posted by the school committee
Running chart, athlete No. 10 printed the post_action method.

The use Condition of with mode can also be applied to Lock/Rlock objects.

Like the following code:

with xuewei_lock:
    do_something()

Equivalent to:

xuewei_lock.acquire()
do_something()
xuewei_lock.release()

This style makes the use of this lock look more elegant and not easy to leak.

After all, sometimes, if you write too many methods carelessly, it's easy to forget them later, especially on multi person collaborative projects. (it is very likely that the latecomers will modify the code in case of a very urgent project, resulting in some cases of lock not being released and system failure, which is a pity.)

summary

The Barrier class uses the resource control unit Condition to implement it, plus a threshold and counter variable to realize the multi-threaded 'Barrier' function.

Other methods readers can read by themselves to deepen their understanding of this class.

For those who like Python, please pay attention to the academic committee Python foundation column or Introduction to Python to master the big column

Continuous learning and continuous development, I'm Lei Xuewei!
Programming is very interesting. The key is to understand the technology thoroughly.
Welcome to wechat, like and support collection!

Keywords: Python Back-end

Added by diddy1234 on Tue, 08 Mar 2022 23:07:30 +0200