同步概念
同步就是协同步调,按预定的先后次序进行运行,如:你说完,我再说。 ‘同’字从字面上容易理解为一起动作
其实不是,‘同’字应是指协同,协助,互相配合。
互斥锁
当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制。
线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引入互斥锁。类似于数据库操作的事务。
互斥锁为资源引入一大状态:锁定/非锁定
某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成”非锁定“,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。
基本操作:
mutex =threading.lock()`
mutex.acquire()
mutex.release()
注意:
- 如果这个锁之前是没有上锁的,那么acquire不会堵塞。
- 如果在调用acquire对这个锁上锁之前,它已经被其他线程上了锁,那么此时acquire会堵塞,直到这个锁被解锁为止。
使用互斥锁
使用互斥锁完成2个线程对同一个全局变量各加100万次的操作
第一步创建一个互斥锁
mutex = threading.Lock()
第二步对线程1进行上锁,完成步骤后解锁
def Text1(nums):
global g_num
# 上锁
mutex.acquire()
for i in range(nums):
g_num += 1
# 解锁
mutex.release()
print("In Text1----",g_num)
第三部对线程2进行上锁,完成步骤后解锁
def Text2(nums):
global g_num
#上锁
mutex.acquire()
for i in range(nums):
g_num += 1
# 解锁
mutex.release()
print("In Text2----",g_num)
总代码
import threading
import time
# global告诉python这是g_num一个全局变量
# threading.Lock:互斥锁 1个开锁,1个关锁 两个方法acquire release
g_num = 0
# 创建一个互斥锁,默认是没有上锁的(全局变量)
mutex = threading.Lock()
def Text1(nums):
global g_num
# 上锁
mutex.acquire()
for i in range(nums):
g_num += 1
# 解锁
mutex.release()
print("In Text1----",g_num)
def Text2(nums):
global g_num
#上锁
mutex.acquire()
for i in range(nums):
g_num += 1
# 解锁
mutex.release()
print("In Text2----",g_num)
def main():
# 分别传入100 和 1000000
t1 = threading.Thread(target= Text1,args=(1000000,))
t2 = threading.Thread(target= Text2,args=(1000000,))
t1.start()
t2.start()
if __name__ == '__main__':
main()