原文地址
学习来源
分类目录——多线程
在第一节中说道多线程更像一种分时获得资源的机制,那么如果线程2需要在线程1的结果基础上才能继续,如果不加限制的话,线程2会在线程1操作未完成之前获得资源,这时候就让线程2开始工作,显然不能get到想要的结果。
编写成前后串行的程序结构是一种解决方案,如果线程2的大多数操作与线程1没有干扰,还是有让它们并行来提高效率的意义的,需要做的就是控制它们对都共同的对象的操作,必须在线程1操作完成之后,线程2才能操作。
上面说的就是一种加锁的机制,线程1在开始操作之前,把冲突的操作对象做加锁操作,达到的效果就是这部分完成之前,其他线程将无法获得时间片。线程1操作结束之后,将锁释放,其他线程(线程2)进而也就可以对共同对象进行操作了
上代码
# import threading
# 多线程实际上并不是真正意义上的
# def job1():
# global A
# for i in range(100):
# A+=1
# print('job1', A)
#
#
# def job2():
# global A
# for i in range(100):
# A+=10
# print('job2', A)
#
# if __name__ == '__main__':
# A = 0
# t1 = threading.Thread(target=job1)
# t2 = threading.Thread(target=job2)
# t1.start()
# t2.start()
# t1.join()
# t2.join()
import threading
def job1():
global A, lock
lock.acquire()
for i in range(100):
A+=1
print('job1', A)
lock.release()
def job2():
global A, lock
lock.acquire()
for i in range(100):
A+=10
print('job2', A)
lock.release()
if __name__ == '__main__':
lock = threading.Lock()
A = 0
t1 = threading.Thread(target=job1)
t2 = threading.Thread(target=job2)
t1.start()
t2.start()
t1.join()
t2.join()
声明一个锁对象lock = threading.Lock()
锁定操作lock.acquire()
解锁操作lock.release()
被注释起来的代码是不含加锁机制的程序,打印结果将会出现job1和job2交错print的混乱结果(每个job的操作很少,如果你的处理器太快的话,可能会发生job1在一个时间片内全部完成,就不会显示出错乱,可以把每个job中的range()中的数字加大来观察交错print的现象)
使用加锁机制后,job2会在job1最终结果A=10的基础上进行操作,print也不会错乱