python-level programming - lock

 lock

          In use with the process modules need to import threading class Lock

 Use locks:

  When multiple threads substantially simultaneously edit a shared data of a certain time, the need for synchronization control
  Thread Synchronization ensures secure access to multiple threads compete for resources, the most simple synchronization mechanism is introduced mutex. 
  Mutex for the introduction of a resource status: locked / unlocked.
 

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()

 

Guess you like

Origin www.cnblogs.com/aitiknowledge/p/11442905.html