线程中的同步, 指的是协调同步, 按照约定的先后次序执行
线程锁的概念
线程锁, 能够把多个语句封装为”一个语句”, 保证操作的原子性, 比如a+=1代码解析后有多个步骤, 多线程共享时就可能出现错误
原子性指的是, 要么不做, 要么做完, 不允许被多个线程同时执行
把多线程可能出错的代码, 用线程锁锁起来, 就可以避免多线程共享变量不安全的情况
python的线程锁
1.创建线程锁
使用threading.Lock方法得到一个锁, 它是一个互斥锁
mutex = threading.Lock()
2.上锁
调用acquire方法上锁
mutex.acquire()
3.解锁
调用release方法解锁
mutex.release()
把可能出错的代码, 放在上锁和解锁之间
线程锁实例
以下代码, 2个线程同时操作一个变量执行+=1操作, 得到的结果是正确的, 如果去掉线程锁, 得到的结果可能比预期的少
import threading
import time
# 定义一个全局变量
gl_num = 0
def test1(num):
global gl_num
for i in range(num):
# 上锁
mutex.acquire()
gl_num += 1
# 解锁
mutex.release()
print("test1------" + str(gl_num))
def test2(num):
global gl_num
for i in range(num):
# 上锁
mutex.acquire()
gl_num += 1
# 解锁
mutex.release()
print("test2---" + str(gl_num))
# 创建一个锁, 默认没有上锁
mutex = threading.Lock()
def main():
t1 = threading.Thread(target=test1, args=(1000000,))
t2 = threading.Thread(target=test2, args=(1000000,))
t1.start()
t2.start()
# 等待子线程运行结束
time.sleep(3)
print("main--" + str(gl_num))
if __name__ == "__main__":
main()
你需要注意的是, 线程锁不要随意使用, 多个锁之间可能造成”死锁”, 例如
假设共有2个锁(x,y), a线程上了x锁, b线程上了y锁, 而a需要y才能解锁, b需要x才能解锁, 那么显然a无法得到y, b也无法得到x, 就会造成相互等待, 从而死锁。