#在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

========================