Python -- 线程安全问题
前言当多个线程同时修改同一数据时,会导致最终的数据出现的不是正确的值所以出现了线程锁,即同一时刻只允许一个线程执行操作,这样可以确保数据的准确性示例代码# @Time: 2021/6/16 9:15import threadingimport timenum = 0# 多个线程操作的全局变量tname = lambda: threading.currentThread().name# 获取当前线程
·
前言
- 当多个线程操作同一数据时,会导致该数据出现的不是正确的值
- 所以出现了线程锁,即同一时刻只允许一个线程执行操作,这样可以确保数据的准确性
示例代码
# -*- coding: utf-8 -*-
# @Author : zbz
import threading
import time
num = 0 # 多个线程操作的全局变量
tname = lambda: threading.currentThread().name # 获取当前线程名称
def task():
print(f"线程开始... ({tname()})")
global num
for j in range(10_0000):
num += 1
print(f"线程结束... ({tname()})")
def main():
t1 = time.time()
ts = []
for j in range(10):
t = threading.Thread(target=task)
ts.append(t)
for t in ts:
t.start()
for t in ts:
t.join()
print(f"num: {num}")
print(f"耗时: {time.time() - t1}")
if __name__ == '__main__':
main()
- 上方代码中,总共有10个线程对全局变量num进行操作,每个线程都是把num的值增加10w
- 所以当所有线程结束后,num正确的值应为 10 × 10w = 100w
代码运行

- 结果并不是100w
- 因为线程并没有上锁
- 运行结束总共耗时0.1s,记住这个时间,后面会说到
上锁
# @Time : 2021/6/16 9:26
import threading
import time
num = 0
lock = threading.Lock() # 线程锁
tname = lambda: threading.currentThread().name
def task():
print(f"线程开始... ({tname()})")
global num
for j in range(10_0000):
lock.acquire() # 获取锁
num += 1
lock.release() # 释放锁
print(f"线程结束... ({tname()})")
def main():
t1 = time.time()
ts = []
for j in range(10):
t = threading.Thread(target=task)
ts.append(t)
for t in ts:
t.start()
for t in ts:
t.join()
print(f"num: {num}")
print(f"耗时: {time.time() - t1}")
if __name__ == '__main__':
main()
- 不难看出,只是在操作num的上下加了获取锁、释放锁这两句代码
- 因为之前就是在同一时刻,有多个线程操作num的值,所以最后num的值才会不准确
代码运行

- 可以看到最后num的值是准确的100w
- 运行结束总共耗时3s,因为上锁的时候,同一时刻只能有一个线程执行,所以其他线程在等待锁的释放,这里消耗了时间,所以时间比之前的不上锁(耗时0.1s)耗费的时间长
更多推荐




所有评论(0)