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