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