Python fourth advanced training notes

Semaphore:

Semaphore is an abstract data type managed by the operating system, which is used to synchronize the use of shared resources in multiple threads. In essence, a semaphore is an internal data used to indicate how many concurrent reads can be made to the current shared resource.

In threading module Semaphore class The semaphore object is implemented, which can be used to control the number of threads obtaining resources. The acquire() and release() methods can be used as the context manager of the with statement. The acquire() method is called when entering, and release() is called when exiting.

Function and application:

It is mainly used in database applications, such as connecting to the database and limiting the number of simultaneous connections, such as database connection pool.
 

As shown in the above figure, define a run method, where parameter n represents the output thread, and x is used to control the extension time of the output thread, where semaphore = threading, seamless (5), and the number five is used to control that the number of threads output each time cannot exceed 5

Conditional variable:

The condition object provided by Python provides support for complex thread synchronization problems. Condition is called a condition variable. In addition to the acquire and release methods similar to Lock, it also provides wait and notify methods.

Construction method:

import threading
# A mutex or reentrant lock can be passed in
cond = threading.Condition()

Instance method:

acquire([timeout])/release(): Call the corresponding method of the associated lock. 
wait([timeout]): Calling this method will cause the thread to enter Condition The waiting pool waits for notification and releases the lock.
    The thread must be locked before use, or an exception will be thrown. 
notify(): Calling this method will select a thread from the waiting pool and notify it. The thread receiving the notification will call it automatically
    acquire()Attempt to obtain a lock (enter the lock pool); Other threads are still waiting in the pool. Calling this method will not
    Release the lock. The thread must be locked before use, or an exception will be thrown. 
notifyAll(): Calling this method will notify all threads in the wait pool that they will enter the lock pool
    Try to get a lock. Calling this method does not release the lock. The thread must be locked before use, or an exception will be thrown

Find a case from the Internet to help understand:

Producer and consumer model, take eating hot pot as an example: there are 10 pieces of meat in a plate of old meat slices. After eating, add them to the pot again

Producer: add old meat slices to the pot, one plate at a time (10 pieces);

Consumer: eat cooked meat slices, mei eat one slice, and the number of meat slices will be reduced by one until finished;

# Import thread module
import threading
import time
 
# Create condition variable condition
con = threading.Condition()
meat_num = 0
 
def thread_consumers():
 # Condition variable condition thread lock
 con.acquire()
 
 # global variable declaration keyword global
 global meat_num
 meat_num = 0
 
 # Wait until the meat slices are cooked
 con.wait()
 while True:
 print("I'll have a piece of meat...")
 meat_num -= 1
 print("Quantity of remaining meat slices:%d"%meat_num)
 time.sleep(0.5)
 if meat_num == 0:
 # When the meat slices are eaten up, inform the boss to add meat slices
 print("Boss, another slice of old meat...")
 con.notify()
 # The meat is eaten up. Wait for the meat
 con.wait()
 
 # Condition variable condition thread releases lock
 con.release()
 
 
def thread_producer():
 # Condition variable condition thread lock
 con.acquire()
 # global variable declaration keyword global
 global meat_num
 
 # The sliced meat is ripe and ready to eat
 meat_num = 10
 print("The sliced meat is ripe and ready to eat...")
 con.notify()
 while True:
 # Blocking function, waiting for the notification that the meat slice is finished
 con.wait()
 meat_num = 10
 # After adding meat slices, you can continue to eat
 print("Meat slices added successfully! Current number of meat slices:%d"%meat_num)
 time.sleep(1)
 con.notify()
 
 con.release()
 
 
if __name__ == "__main__":
 # Create and initialize threads
 t1 = threading.Thread(target=thread_producer)
 t2 = threading.Thread(target=thread_consumers)
 
 # Start thread -- pay attention to the start sequence of threads. The start sequence is very important
 t2.start()
 t1.start()
 
 # Block the main thread and wait for the child thread to end
 t1.join()
 t2.join()
 
 print("The program is over!")

Event:

Event: the mechanism of event processing: a built-in Flag is defined globally. If the Flag value is False, when the program executes event If the Flag value is True, then event The wait method is no longer blocked.

Event is actually a simplified version of Condition. Event has no lock and cannot put the thread into synchronization blocking state.

Event()

  • set(): set the flag to True and notify all threads in the waiting blocking state to resume running state.

  • clear(): set the flag to False.

  • wait(timeout): if the flag is True, it will be returned immediately. Otherwise, the thread will be blocked to the waiting blocking state and wait for other threads to call set().

  • isSet(): gets the built-in flag status and returns True or False.

Case:

Small partners a and b are ready when they receive the notification event When set (), threads a and b will be executed

# coding:utf-8

import threading
import time

event = threading.Event()


def chihuoguo(name):
    # Wait for the event and enter the wait blocking state
    print '%s Already started' % threading.currentThread().getName()
    print 'buddy %s Has entered the dining state!'%name
    time.sleep(1)
    event.wait()
    # Enter the running state after receiving the event
    print '%s Got the notice.' % threading.currentThread().getName()
    print 'buddy %s Start eating!'%name

# Set thread group
threads = []

# Create a new thread
thread1 = threading.Thread(target=chihuoguo, args=("a", ))
thread2 = threading.Thread(target=chihuoguo, args=("b", ))

# Add to thread group
threads.append(thread1)
threads.append(thread2)

# Open thread
for thread in threads:
    thread.start()

time.sleep(0.1)
# Send event notification
print 'The main thread informs the child to eat!'
event.set()

Operation results:

Thread-1 Already started
 buddy a Has entered the dining state!
Thread-2 Already started
 buddy b Has entered the dining state!
The main thread informs the child to eat!
Thread-1 Got the notice.
buddy a Start eating!
Thread-2 Got the notice.
buddy b Start eating!

 

Keywords: Python Back-end

Added by jeff8j on Sun, 09 Jan 2022 13:50:08 +0200