python3中全局变量问题的多线程处理

2024-09-24 06:32:28 发布

您现在位置:Python中文网/ 问答频道 /正文

代码如

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')

为什么我没有得到我期望的结果


Tags: inlocktargetfordefrangeglobalthread
1条回答
网友
1楼 · 发布于 2024-09-24 06:32:28

Python不能保证线程何时运行。显然,Python开始执行job1()线程,在开始运行job2()线程之前,它一直运行到完成,完成了循环的所有10次迭代

无法预测两个线程将如何调度。出于这个原因,像您这样信任任何类型的全局资源共享,而不使用某种控件,如锁、信号量或线程安全类,在大多数情况下都是自找麻烦。因此,代码的锁定版本虽然不能提供所需的输出,但可以更好地考虑让这两个线程一起工作

顺便说一句,您不需要在函数中调用global lock。这只允许您将全局lock引用指向不同的Lock对象,或者以其他方式更改该变量的内容。Lock对象的行为不会受到该调用的影响

相关问题 更多 >