7-[Multithreading]-Event, Timer, Queue, Stack

1. Event object

A key characteristic of threads is that each thread runs independently and has an unpredictable state.
If other threads in the program need to determine their next operation by judging the state of a thread, the thread synchronization problem will become very difficult.
To solve these problems, we need to use the Event object from the threading library.
The object contains a signal flag that can be set by a thread, which allows the thread to wait for some event to occur.
In the initial case, the signal flag in the Event object is set to false.
If there is a thread waiting for an Event object, and the flag of the Event object is false, then the thread will be blocked until the flag is true.
If a thread sets the signal flag of an Event object to true, it will wake up all threads waiting for the Event object.
If a thread waits for an Event object that has been set to true, then it ignores the event and continues execution

  

 

from threading import Event

event.isSet(): Returns the state value of the event;
event.wait(): If event.isSet()==False, the thread will be blocked;
event.set(): Set the state value of event to True, all threads in the blocking pool are activated and enter the ready state, waiting for the operating system to schedule;
event.clear(): restores the event's status to False.

  

 

In the timeout of 3s, refresh, re-execute the program and wait, signal flag

  

 

 

2. Event application: connect to the database

For example, there are multiple worker threads trying to connect to MySQL, we want to make sure that the MySQL service is working properly before connecting those worker threads to connect to the MySQL server,

If the connection is unsuccessful, it will try to reconnect. Then we can use the threading.Event mechanism to coordinate the connection operation of each worker thread

(1) Primary version

from threading import Thread, Event, currentThread
import time

event = Event()


def conn():
    print('%s is connecting' % currentThread().getName())
    event.wait() #Default         is False blocking, when it becomes True, the program is released 
    print ( ' %s is connected ' % currentThread().getName())


def check():
    print('%s is checking' % currentThread().getName())
    time.sleep(5)       
    event.set()     # The signal flag of the Event object is not set to True

if __name__ == '__main__':
    for i in range(3):
        t = Thread(target=conn)
        t.start()

    t = Thread(target=check)
    t.start()

 

(2) Intermediate version

# Event object that allows threads to wait for something to happen

from threading import Thread, Event, currentThread
import time

event = Event()

    
def conn():
    n = 0
    while not event.is_set():
        print('%s is connecting  %s times' % (currentThread().getName(), n))
        event.wait(0.5)
        if n == 3:
            print('%s try more times' % currentThread().getName())
            break
        n += 1

    print('%s is connected' % currentThread().getName())


def check():
    print('%s is checking' % currentThread().getName())
    time.sleep(5)
    event.set()

if __name__ == '__main__':
    for i in range(3):
        t = Thread(target=conn)
        t.start()

    t = Thread(target=check)
    t.start()

 

 (3) Courseware version

from threading import Thread,Event
import threading
import time,random
def conn_mysql():
    count =1
     while  not event.is_set():
         if count > 3 :
             raise TimeoutError( ' Connection timed out ' )
         print ( ' <%s> %s attempt to link ' % (threading.current_thread().getName(), count))
        event.wait(0.5)
        count+=1
    print('<%s>链接成功' %threading.current_thread().getName())


def check_mysql():
     print ( ' \033[45m[%s] checking mysql\033[0m ' % threading.current_thread().getName())
    time.sleep (random.randint ( 2,4 ))
    event.set()
if __name__ == '__main__':
    event=Event()
    conn1=Thread(target=conn_mysql)
    conn2=Thread(target=conn_mysql)
    check=Thread(target=check_mysql)

    conn1.start()
    conn2.start()
    check.start()

 

3. Timer

 

  (1) Verification code function

from threading import Timer
import time
import random
import string


#Verification code function # 3s verification code refresh once


class Code(object):
     #Generate a verification code 
    def make_code(self):
        code_list = random.sample(string.ascii_letters, 4)
        self.ret = ''.join(code_list)
        print(self.ret)

        # >>> help(random.sample) get help 
        # >>> random.sample(string.ascii_letters, 4) 
        # ['W', 'B', 'g', 'n']

    #Enter a verification code 
    def enter_code(self):

        self.make_code()
        choice = input( ' Enter verification code >>> ' ).strip()
         if choice.upper() == self.ret.upper():
             print ( ' Verification successful ' )
         else :
             print ( ' Verification failed ' )
 if  __name__ == ' __main__ ' :
    c = Code()
    c.enter_code()

  

 

   (2) Refresh the verification code regularly

 

 

 

  (3) Courseware version

from threading import Timer
import random

class Code(object):
    def __init__(self):
        self.make_cache()

    def make_cache(self, interval=5):
        self.cache = self.make_code()
        print(self.cache)
        self.t = Timer(interval, self.make_cache)
        self.t.start()

    def make_code(self, n=4):
        ret = ''
        for i in range(n):
            s1 = str(random.randint(0, 9))
            s2 = chr(random.randint(65, 90))
            ret += random.choice([s1, s2])

        return right

    def check(self):
        while True:
            code = input( ' Enter the verification code >>> ' ).strip()
             if code.upper() == self.cache:
                 print ( ' Input successful ' )
                self.t.cancel()
                break

obj = Code()
obj.check()

 

4. Thread queue

queue is especially useful in threaded programming when information must be exchanged safely between multiple threads.

There are three different usages

(1) Queue: first in first out

class queue.Queue(maxsize=0) #Queue: first in first out

  

 

(2) Stack: last in first out

class queue.LifoQueue(maxsize=0) #堆栈:last in fisrt out

 

 (3) Priority queue

class queue.PriorityQueue(maxsize=0) #Priority queue: A queue that can set priorities when storing data

  

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324770775&siteId=291194637