python锁

锁的概念是因为多线程而提出的,必须在线程中才能体现出锁的作用。

没用锁的情况:

import threading
import time

gl_num = 0

def show(arg):
    global gl_num
    n = gl_num
    time.sleep(1)
    gl_num = n+1
    print(gl_num)

for i in range(10):
    t = threading.Thread(target=show, args=(i,))
    t.start()

print ('main thread stop')
没用锁的代码
main thread stop
1
1
1
1
1
1
1
1
1
1
运行结果

可以看到,在没用锁的情况下,线程同时取到0并加1,结果都为1.

什么是锁?

  锁,跟门锁一样,他的作用不是为了锁定这个门,而是为了锁定门后的一方世界,也就是代码块。

  

import threading
import time

lock = threading.RLock()
gl_num = 0
def show(arg):
    lock.acquire()
    global gl_num
    n = gl_num
    time.sleep(1)
    gl_num = n+1
    lock.release()
    print(gl_num)

for i in range(10):
    t = threading.Thread(target=show, args=(i,))
    t.start()

print ('main thread stop')
加上锁
main thread stop
1
2
3
4
5
6
7
8
9
10
结果

锁都有那些呢?

  两种:Lock(指令锁、RLock(可重入锁)。Lock属于全局,Rlock属于线程。

学习lock和Rlock区别前,我们要搞清楚什么事死锁。

死锁是:比如一辆车被两把锁锁住,你单单拿到一把锁的钥匙,你是开不了这个车的,这就是死锁。当然,这里是抽象的锁概念跟现实还有很大区别。

import threading
import time

lock = threading.Lock()
gl_num = 0
def show(arg):
    lock.acquire()
    print('我只执行一次就被锁住了。',threading.current_thread().name)
    lock.acquire()
    time.sleep(1)
    print(threading.current_thread().name)
    lock.release()
    lock.release()


for i in range(10):
    t = threading.Thread(target=show, args=(i,))
    t.start()

print ('main thread stop')
死锁
我只执行一次就被锁住了。 Thread-1
main thread stop
结果

那么这死锁怎么解决?呵呵,用Rlock,这因为就是他们的区别了。

import threading
import time

lock = threading.RLock()
gl_num = 0
def show(arg):
    lock.acquire()
    print('我只执行一次就被锁住了。',threading.current_thread().name)
    lock.acquire()
    time.sleep(1)
    print(threading.current_thread().name)
    lock.release()
    lock.release()


for i in range(10):
    t = threading.Thread(target=show, args=(i,))
    t.start()

print ('main thread stop')
Rlock解决死锁,代码几乎不变
我只执行一次就被锁住了。 Thread-1
main thread stop
Thread-1
我只执行一次就被锁住了。 Thread-2
Thread-2
我只执行一次就被锁住了。 Thread-3
Thread-3
我只执行一次就被锁住了。 Thread-4
Thread-4
我只执行一次就被锁住了。 Thread-5
Thread-5
我只执行一次就被锁住了。 Thread-6
Thread-6
我只执行一次就被锁住了。 Thread-7
Thread-7
我只执行一次就被锁住了。 Thread-8
Thread-8
我只执行一次就被锁住了。 Thread-9
Thread-9
我只执行一次就被锁住了。 Thread-10
Thread-10
结果

 总结

1、线程如果共用同一个数据(栈、队列),如果相互之间存在数据污染,那么就需要锁的来将操作公共数据的代码块锁起来。

2、锁的获取:lock = threading.Lock()或者lock = threading.RLock(),

3、lock跟RLock的区别,使用多把锁,那就需要Rlock来解决死锁问题。这里说的多把锁,是指一个锁多个嵌套。

原文地址:https://www.cnblogs.com/hardykay/p/10203275.html