120 python program thread operations - locks

First, the synchronization lock

1.1 plurality of threads to seize resources

from threading import Thread,Lock
x = 0
def task():
    global x

    for i in range(200000):
        x = x+1
        # t1 的 x刚拿到0 保存状态 就被切了
        # t2 的 x拿到0 进行+1       1
        # t1 又获得运行了  x = 0  +1  1
        # 这就产生了数据安全问题.
if __name__ == '__main__':
    # 使用的是操作系统的原生线程.
    t1 = Thread(target=task)
    t2 = Thread(target=task)
    t3 = Thread(target=task)
    t1.start()
    t2.start()
    t3.start()

    t1.join()
    t2.join()
    t3.join()
    print(x)

1.2 for common data lock operation

import threading
lock = threading.Lock()
lock.acquire() # 锁头
'''
公共数据的一系列操作 
'''
lock.replease() # 释放锁

1.3 genlock reference

from threading import Thread,Lock

x = 0
mutex = Lock()
def task():
    global x

    mutex.acquire()
    for i in range(200000):
        x = x+1
    mutex.release()

if __name__ == '__main__':
    
    # 使用的是操作系统的原生线程.
    t1 = Thread(target=task)
    t2 = Thread(target=task)
    t3 = Thread(target=task)
    t1.start()
    t2.start()
    t3.start()

    t1.join()
    t2.join()
    t3.join()
    print(x) #结果肯定是600000,由原来的并发执行变成串行,牺牲了执行效率保证了数据安全

Since the lock will become a serial run, then I start to use immediately after the join, would not lock, ah, ah is the serial effect

Yes: use immediately after start jion, certainly will execute the task becomes 100 serial, without a doubt, the end result is certainly n is 0, it is safe, but the problem is

join immediately after start: all code within the tasks are executed serially, and lock, the lock portion that is only the modified portion is shared serial data

From single to ensure data security, both can be achieved, but it is clearly higher efficiency locked.

Second, the deadlock with recursive lock

The so-called deadlock: refers to the phenomenon of two or more processes or threads in the implementation process, a result of competition for resources caused by waiting for each other, in the absence of external force, they will not be able to promote it. At this time, say the system is in deadlock state or system to produce a deadlock, which is always in the process of waiting for another process called the deadlock, deadlock is as follows

2.1 Deadlock examples

from threading import Thread,Lock
mutex1 = Lock()
mutex2 = Lock()
import time
class MyThreada(Thread):
    def run(self):
        self.task1()
        self.task2()
    def task1(self):
        mutex1.acquire()
        print(f'{self.name} 抢到了 锁1 ')
        mutex2.acquire()
        print(f'{self.name} 抢到了 锁2 ')
        mutex2.release()
        print(f'{self.name} 释放了 锁2 ')
        mutex1.release()
        print(f'{self.name} 释放了 锁1 ')

    def task2(self):
        mutex2.acquire()
        print(f'{self.name} 抢到了 锁2 ')
        time.sleep(1)
        mutex1.acquire()
        print(f'{self.name} 抢到了 锁1 ') # 程序在这里的时候会卡住
        mutex1.release()
        print(f'{self.name} 释放了 锁1 ')
        mutex2.release()
        print(f'{self.name} 释放了 锁2 ')


for i in range(3):
    t = MyThreada()
    t.start()

Thread-1 grab lock 1
Thread-1 grab lock 2
Thread-1 release lock 2
Thread-1 release lock 1
Thread-1 grab lock 2
the Thread-lock 1 2 grab

**: Thread 1 second after sleep1 got a lock, but in the process 1sleep thread, the operating system has to schedule other threads, another thread to get the lock runs 2, and when the thread got lock 2:00 sleep time, cpu and scheduled to execute a thread 1, thread 1 but this time has been released lock 1, 2 need to lock, but lock 2 at this time has been to get the thread 2 has not yet released, and then to thread 2 the conditions under execution is to get the lock 1, that is, can be understood as:

Thread 1 get 1 lock, no release

Thread 2 get 2 lock, no release

Thread 1 conditional execution is to get locked down 2

Thread 2 is to get down the conditions for the implementation of the lock 1

This time, there is a problem of resource consumption, the program would have been stuck there, resulting in a deadlock

Resolved to put law: recursive lock

Recursive locks, in order to support Python, in the same thread multiple requests for the same resource, python provides reentrant lock RLock.

This internal RLock maintains a Lock and a counter variable, counter records the number of times acquire, so that resources can be many times require. Acquire a thread until all have been release, other threads to get resources. The above example if instead of using RLock Lock, deadlock will not occur.

Only under one thread can repeatedly acquire, acquire will release several times

2.2 recursive lock to solve the deadlock problem

from threading import Thread,Lock,RLock
# 递归锁 在同一个线程内可以被多次acquire
# 如何释放 内部相当于维护了一个计数器 也就是说同一个线程 acquire了几次就要release几次
# mutex1 = Lock()
# mutex2 = Lock()
mutex1 = RLock()
mutex2 = mutex1

import time
class MyThreada(Thread):
    def run(self):
        self.task1()
        self.task2()
    def task1(self):
        mutex1.acquire()
        print(f'{self.name} 抢到了 锁1 ')
        mutex2.acquire()
        print(f'{self.name} 抢到了 锁2 ')
        mutex2.release()
        print(f'{self.name} 释放了 锁2 ')
        mutex1.release()
        print(f'{self.name} 释放了 锁1 ')

    def task2(self):
        mutex2.acquire()
        print(f'{self.name} 抢到了 锁2 ')
        time.sleep(1)
        mutex1.acquire()
        print(f'{self.name} 抢到了 锁1 ')
        mutex1.release()
        print(f'{self.name} 释放了 锁1 ')
        mutex2.release()
        print(f'{self.name} 释放了 锁2 ')


for i in range(3):
    t = MyThreada()
    t.start()

# 此时程序将会正常执行结束

Third, the semaphore

Keywords: Semaphore

Semaphore is a class that requires an argument, the argument is an integer, while representatives can have multiple threads can get multi-lock

On behalf of several parameters is how many threads to pick up a few locks can be executed

from threading import Thread,currentThread,Semaphore
import time

def task():
    sm.acquire()
    print(f'{currentThread().name} 在执行')
    time.sleep(3)
    sm.release()

sm = Semaphore(5)
for i in range(15):
    t = Thread(target=task)
    t.start()

Guess you like

Origin www.cnblogs.com/xichenHome/p/11569104.html