Python同步锁
多线程是共用一个进程空间的,当多个线程要用到相同的数据,那么久会存在资源竞争和锁的问题。
锁是用来实现共享资源的同步访问。为每一个共享资源创建一个Lock对象,当需要访问共享资源的时候,调用acquire方法来获取锁对象,如果其他线程已经得到了该锁,那就需要等待其他线程释放。等资源访问后,就需要调用release方法来释放锁。
不加锁
import threading
import time
num=100
def fun_sub():
global num
num2=num
time.sleep(0.01)
num=num2-1
if __name__=='__main__':
thread_list=[]
for thread in range(100):
t=threading.Thread(target=fun_sub)
t.start()
thread_list.append(t)
for t in thread_list:
t.join()
print('num',num)
定义了一个全局变量,此时存在资源竞争的现象。
加锁
import threading
import time
num=100
def fun_sub():
global num
lock.acquire() #加锁到释放后的代码只能一个线程可以运行
print('加锁')
num2=num
time.sleep(0.01)
num=num2-1
print('释放锁')
lock.release()
if __name__=='__main__':
thread_list=[]
lock=threading.Lock() #创建一把同步锁
for thread in range(100):
t=threading.Thread(target=fun_sub) #创建100个线程
t.start()
thread_list.append(t)
for t in thread_list:
t.join()
print('num',num)
死锁
python中多个线程在共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁,这个时候两个线程将会一直等待下去。
import threading
import time
lock = threading.Lock()
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
self.fun1()
self.fun2()
def fun1(self):
lock.acquire() # 如果锁被占用,则阻塞在这里,等待锁的释放
print ("线程 %s , 想拿: %s--%s" %(self.name, "苹果",time.ctime()))
lock.acquire()
print ("线程 %s , 想拿: %s--%s" %(self.name, "香蕉",time.ctime()))
lock.release()
lock.release()
def fun2(self):
lock.acquire()
print ("线程 %s , 想拿: %s--%s" %(self.name, "香蕉",time.ctime()))
# time.sleep(0.01)
lock.acquire()
print ("线程 %s , 想拿: %s--%s" %(self.name, "苹果",time.ctime()))
lock.release()
lock.release()
if __name__ == "__main__":
for i in range(0, 10): #建立10个线程
my_thread = MyThread() #类继承法是python多线程的另外一种实现方式
my_thread.start()
递归锁
import threading
import time
lock = threading.RLock() #递归锁
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
self.fun1()
self.fun2()
def fun1(self):
lock.acquire() # 如果锁被占用,则阻塞在这里,等待锁的释放
print ("线程 %s , 想拿: %s--%s" %(self.name, "苹果",time.ctime()))
lock.acquire()
print ("线程 %s , 想拿: %s--%s" %(self.name, "香蕉",time.ctime()))
lock.release()
lock.release()
def fun2(self):
lock.acquire()
print ("线程 %s , 想拿: %s--%s" %(self.name, "香蕉",time.ctime()))
# time.sleep(0.01)
lock.acquire()
print ("线程 %s , 想拿: %s--%s" %(self.name, "苹果",time.ctime()))
lock.release()
lock.release()
if __name__ == "__main__":
for i in range(0, 10): #建立10个线程
my_thread = MyThread() #类继承法是python多线程的另外一种实现方式
my_thread.start()