lock
Use locks:
Lock syntax
Create a lock, lock to lock, the lock is released
from Threading Import Lock # create lock mutex = Lock () # acquire the lock (lock) mutex.acquire () # release lock (unlock) mutex.release ()
acquire () method of locking the lock can accept a blocking process parameter,
If blocking is set to True, the current thread will be blocked until this date to get a lock (if not specified, the default is True)
If blocking is set to False, the current thread will not be blocked
Locking and unlocking process (assuming that is multi-threaded scheduling):
This lock is usually a shared resource services, namely multiple threads simultaneously using shared resources. This locks the same time only one thread scheduling, another thread is blocked, currently scheduled thread releases the lock, the blocked thread can be scheduled.
Lock advantages:
To ensure that certain key code can only be a complete implementation of a thread from beginning to end.
Lock disadvantages:
Organized a concurrent execution of multiple threads, a piece of code that contains virtually lock can only be performed in a single-threaded mode, efficiency is greatly reduced; there may be multiple lock code, if multiple threads have multiple locks, likely to cause deadlock.
Deadlock phenomenon (example):
# Deadlock neither needs the other to release the lock, and happens to be the condition for the release of the other party to acquire the lock release needed # thread 1 class MyThread1 (threading.Thread): DEF __init__ (Self): . Super () __init__ () DEF RUN (Self): # thread 1 obtain A lock IF mutexA.acquire (): Print (self.name + " ----- ----- DO1 --- up " ) SLEEP ( 1 ) # At this thread 2 B acquired lock, it is necessary to release the waiting thread 2 B lock IF mutexB.acquire (): Print (self.name + " ----- ----- DO1 --- Down " ) mutexB.release () mutexA.release () # Thread 2 class MyThread2 (of the threading.Thread): DEF the __init__ (Self): . Super () the __init__ () DEF RUN (Self): # Thread 2 acquires the lock B IF mutexB.acquire (): Print (self.name + " ----- ----- DO2 --- up " ) SLEEP ( 1 ) # At this thread 1 acquires a lock, you need to wait for the release of a lock thread 1 IF mutexA .acquire (): Print (self.name + " ----- ----- DO2 --- Down ") MutexA.release () mutexB.release () mutexA = of threading.Lock () mutexB = of threading.Lock () IF the __name__ == ' __main__ ' : # Thread 1 and Thread 2 while performing T1 = MyThread1 () T2 = MyThread2 ( ) t1.start () t2.start ()
:( bankers avoid deadlock algorithm method, see examples)
# 银行家算法 class Task1(threading.Thread): def __init__(self): super().__init__() def run(self): while True: if lock1.acquire(): print("Task1".center(20, "-")) sleep(0.5) lock2.release() class Task2(threading.Thread): def __init__(self): super().__init__() def run(self): while True: if lock2.acquire(): print("Task2".center(20, "-")) sleep(0.5) lock3.release() class Task3(threading.Thread): def __init__(self): super().__init__() def run(self): while True: if lock3.acquire(): print("Task3".center(20, "-")) sleep(0.5) lock1.release() lock1 = threading.Lock() lock2 = threading.Lock() lock3 = threading.Lock() lock2.acquire() lock3.acquire() t1 = Task1() t2 = Task2() t3 = Task3() t1.start() t2.start() t3.start()
Multi-process and multi-threaded compare and choose
Whether to adopt multi-tasking, our mission depends on the type of
If it is computationally intensive, requires a lot of CPU resources for computing, critical operational efficiency of the code, such a task generally do not use multiple threads, because of frequent task scheduler will slow down the CPU
operation.
If the IO-intensive tasks related to the hard disk read and write, read and write the network, the more time waiting for IO operation is complete, you can put this type of multi-threaded task or process to carry out.
(Time to achieve the same code with) single-threaded, multi-threaded, multi-process
# Single-threaded, multi-threaded, multi-process and different # simple summation DEF fib (the X-): RES = 0 for i in the Range (100000000 ): RES + = i * the X- return RES # factorial DEF FAC (the X-) : IF X <2 : return . 1 return X * FAC (. 1-X ) # simple summation DEF SUM (X): RES = 0 for I in Range (50000000 ): RES + = I *x return res # 函数列表 funcs = [fib, fac, sum] n = 100 class MyThread(threading.Thread): def __init__(self, func, args, name=""): super().__init__() self.name = name self.func = func self.args = args self.res = 0 def getResult(self): return self.res def run(self): print("starting ", self.name, " at: ", ctime()) self.res = self.func(self.args) print(self.name, "finished at: ", ctime()) def main(): nfuncs = range(len(funcs)) print("单线程".center(30, "*")) start = time() for i in nfuncs: print("start {} at: {}"(. funcs [I] .format the __name__ , the ctime ())) start_task = Time () Print (funcs [I] (n-)) end_task = Time () Print ( " consuming tasks: " , end_task- start_task) Print ( " {} Finished AT: {} " (. funcs [I] .format the __name__ , the ctime ())) end = time () Print ( " single-threaded runtime: " , eND- Start) Print ( " single-threaded ends: " .center (30," * " )) Print () Print ( " multi-threaded " .center (30, " * " )) Start = Time () Threads = [] for I in nfuncs: # a binding thread a function t = MyThread (funcs [I], n-, funcs [I]. the __name__ ) threads.append (T) for I in nfuncs: # simultaneously starting a thread threads [I] .start () for I in nfuncs: Threads [I] .join () Print (Threads [I] .getResult ()) End = Time () Print ( " multi-thread runtime: " , END- Start) Print ( " Multithreading End: " .center (30, " * " )) Print ( ) Print ( " multi-process " .center (30, " * " )) Start = Time () process_list = [] for i in nfuncs: # a process to bind a function Process = T (target = funcs [I], args = (n-,)) process_list.append (T) for I in nfuncs: # simultaneously start the process process_list [I] .start () for I in nfuncs: process_list [I] .join () end = time () Print ( " multi-process run time: " , end - Start) Print ( " multi-process ends: " .center (30, " * " )) IF __name__ == " __main__ " : main()