代码如
import threading
def job1():
global A
for i in range(10):
A += 1
print('job1', A)
def job2():
global A
for i in range(10):
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()
print('all done')
我在python 3.7.3上运行它
我想要得到的结果是
job1job2 111
job1job2 1222
job1job2 2333
job1job2 3444
job1job2 4555
job1job2 5666
...
all done
但我得到的是
job1 1
job1 2
job1 3
job1 4
job1 5
job1 6
job1 7
job1 8
job1 9
job1 10
job2 20
job2 30
job2 40
job2 50
job2 60
job2 70
job2 80
job2 90
job2 100
job2 110
all done
但我就是没用锁
我认为这是以下代码的结果:
import threading
def job1():
global A, lock
lock.acquire()
for i in range(10):
A += 1
print('job1', A)
lock.release()
def job2():
global A, lock
lock.acquire()
for i in range(10):
A += 10
print('job2', A)
lock.release()
if __name__ == '__main__':
A = 0
lock = threading.Lock()
t1 = threading.Thread(target=job1)
t2 = threading.Thread(target=job2)
t1.start()
t2.start()
t1.join()
t2.join()
print('all done')
为什么我没有得到我期望的结果
Python不能保证线程何时运行。显然,Python开始执行
job1()
线程,在开始运行job2()
线程之前,它一直运行到完成,完成了循环的所有10次迭代无法预测两个线程将如何调度。出于这个原因,像您这样信任任何类型的全局资源共享,而不使用某种控件,如锁、信号量或线程安全类,在大多数情况下都是自找麻烦。因此,代码的锁定版本虽然不能提供所需的输出,但可以更好地考虑让这两个线程一起工作
顺便说一句,您不需要在函数中调用
global lock
。这只允许您将全局lock
引用指向不同的Lock
对象,或者以其他方式更改该变量的内容。Lock
对象的行为不会受到该调用的影响相关问题 更多 >
编程相关推荐