#在threading模块当中,定义一个Lock类,可以方便的处理锁定:(线程之间的锁是互斥的)
#互斥锁 ''' 当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制。 线程同步能够保证多个线程安全访问“竞争资源”,最简单的同步机制就是引用互斥锁。 互斥锁为资源引入一个状态:锁定/非锁定状态。 某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其它线程不能更改; 直到当前线程释放资源,将资源变成"非锁定"状态,其它的线程才能再次锁定该资源。 互斥锁保证了每次只有一个线程进行“写操作”,从而保证多个线程数据正确性。 ''' #上锁/解锁过程 ''' 当一个线程调用锁的acquire()方法获取锁时,锁就进行“锁定(Locked)”状态。 每次只有一个线程可以获得这个锁。如果此时另一个线程试图获取锁中的资源,该线程就会变为“阻塞”状态。 直到拥有锁的那个线程执行release(),锁就变成“非锁定(Unlocked)”状态。 线程调试程序从处于同步阻塞状态的线程中选择一个来获得锁,并使得该线程进入“运行(running)”状态。 '''# #1、创建锁 # mutex = threading.Lock() # # #2.锁定 # mutex.acquire(True/Flase) ''' True:如果所要获取的资源已经“锁定”,表示当前线程处地等待(阻塞),直到获取到这个锁为止--默认值 False:不阻塞,即不管本次调用能够成功上锁,都不会卡在这,而是继续执行后面的代码。 ''' # # #3.解锁 # mutex.release()from threading import Lock from threading import Thread import time #全局变量g_num= 0 def w1(): global g_num for i in range( 1000000): m_flag=m.acquire( True) #判断是否上锁,上了锁才可以执行并解锁 if m_flag: g_num+= 1 m.release() print( "w1---g_num=%d" % g_num) def w2(): global g_num for i in range( 1000000): m_flag=m.acquire( True) #若为False,即不阻塞(不等待),跳过需要枷锁执行的代码,继续执行下面的代码,会出错
if m_flag: g_num += 1 m.release() print( "w2---g_num=%d" % g_num) if __name__ == "__main__": # 创建锁 m = Lock() t1 = Thread( target=w1) t1.start() #time.sleep(1)#如果加入时间阻塞,就不是并行 t2 = Thread( target=w2) t2.start() ''' #问题产生的原因就是没有控制多个线程对同一资源的访问,对数据造成破坏,使得线程运行的结果不要预期。 #这种现象我们称为“线程不安全” 解决思路: 1.t1被调用的时候,获取g_num =0,然后上一把锁, 即不允许其它线程操作num. 2.对num进行加1 3.解锁,g_num = 1,其它的线程就可以使用g_num的值 ,而且g_num的值不是原来的0 4.同理其它线程在对num进行修改时,都要先上锁,处理完成后再解锁。 在上锁的整个过程中,不允许其它线程访问,保证了数据的正确性 '''
/Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6 /Users/apple/PycharmProjects/stage4/thread/t11.py
w2---g_num=1871349
w1---g_num=2000000
Process finished with exit code 0
========================