#在threading模块当中定义了一个Lock类,可以方便的使用锁定: # #1.创建锁 # mutex = threading.Lock() # # #2.锁定 ''' mutex.acquire(True/False) True:如果所要获取的资源已经"锁定",表示当前线程处地等待(阻塞),直到获取到这个锁为止--默认值 False:不阻塞,即不管本次调用能够成功上锁,都不会卡在这,而是继续执行后面的代码 ''' # #3.解锁 # mutex.release() import threading,time #全局变量 g_num = 0 def w1(): global g_num for i in range(10000000): #上锁 mutexFlag = mutex.acquire(True) if mutexFlag: g_num+=1 #解锁 mutex.release() print("test1---g_num=%d"%g_num) def w2(): global g_num for i in range(10000000): # 上锁 mutexFlag = mutex.acquire(True) if mutexFlag: g_num+=1 # 解锁 mutex.release() print("test2---g_num=%d" % g_num) if __name__ == "__main__": #创建锁 mutex = threading.Lock() t1 = threading.Thread(target=w1) t1.start() t2 = threading.Thread(target=w2) t2.start() #互斥锁 ''' 当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制. 线程同步能够保证多个线程安全访问,"竞争资源",最简单的同步机制就是引用互斥锁 互斥锁为资源引入一个状态:锁定/非锁定状态 某个线程要更改共享数据时,先将其锁定,此时资源的状态是锁定状态,其他线程不能更改 直到当前线程释放资源.将资源变成"非锁定"状态,其他的线程才能再次锁定该资源 互斥锁保证了每次只有一个线程进行"写操作",从而保证多个线程的正确性 上锁/解锁过程 当一个线程调用锁的acquire()方法获取琐时,锁就进行锁定"Locked"状态 每次只有一个线程可以获得这个锁,如果此时拎一个线程试图获取锁中的资源,该线程就会变成"阻塞"状态 直到拥有锁的那个线程执行release(),锁就变成"非锁定(Unlocked)"状态 线程调试程序从处于同步阻塞状态的线程中选择一个来获得锁,并使得该线程进入"运行(running)状态" 总结: 锁的好处: 1.确定了某一段代码只能由一个线程来从头到尾完整的执行 2.全局变量的安全 锁的坏处: 1.阻止了多线程的并发执行,包含锁的某段代码实际上只能以单线程模块执行,效率大大的下降了 2.由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成"死锁". '''