Python同步锁
多线程是共用一个进程空间的,当多个线程要用到相同的数据,那么久会存在资源竞争和锁的问题。
锁是用来实现共享资源的同步访问。为每一个共享资源创建一个Lock对象,当需要访问共享资源的时候,调用acquire方法来获取锁对象,如果其他线程已经得到了该锁,那就需要等待其他线程释放。等资源访问后,就需要调用release方法来释放锁。
不加锁
import threading
import timenum=100
def fun_sub():global numnum2=numtime.sleep(0.01)num=num2-1if __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 timenum=100
def fun_sub():global numlock.acquire() #加锁到释放后的代码只能一个线程可以运行print('加锁')num2=numtime.sleep(0.01)num=num2-1print('释放锁')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 timelock = 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 timelock = 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()