Python线程锁在简单示例中不起作用

lou*_*lou 4 python multithreading locking python-multithreading

我必须在这里遗漏一些东西但是这个试图修改函数中的全局变量的两个线程的简单示例没有给出预期的结果:

from threading import Thread, Lock
some_var = 0

def some_func(id):
    lo = Lock()
    with lo:
        global some_var
        print("{} here!".format(id))
        for i in range(1000000):
            some_var += 1
        print("{} leaving!".format(id))


t1 = Thread(target=some_func, args=(1,))
t2 = Thread(target=some_func, args=(2,))
t1.start()
t2.start()
t1.join()
t2.join()
print(some_var)
Run Code Online (Sandbox Code Playgroud)

输出:

1 here!
2 here!
2 leaving!
1 leaving!
1352010
Run Code Online (Sandbox Code Playgroud)

正如你所看到的那样,两个线程都会进入同时被锁定的部分,并且globel变量'some_var'的增量会因此而混淆.

看起来Lock由于某种原因不起作用.对于高达10000的范围,它正在工作,但这可能仅仅是因为在这样的短计算期间没有释放GIL.

到底是怎么回事?

我正在使用Python3.3.2 64位

The*_*nse 7

Lock()函数创建一个全新的锁 - 只有调用该函数的线程才能使用.这就是为什么它不起作用,因为每个线程都锁定一个完全不同的锁.

锁定项是您可以在没有任何问题的情况下声明为全局的少数几项内容之一,因为您绝对希望每个线程看到相同的内容Lock().你应该试试这个:

from threading import Thread, Lock
some_var = 0
lo = Lock()

def some_func(id):
    global lo
    with lo:
        global some_var
        print("{} here!".format(id))
        for i in range(1000000):
            some_var += 1
        print("{} leaving!".format(id))
Run Code Online (Sandbox Code Playgroud)


小智 5

每次调用函数时,都会创建一个新锁,因此每个不同的线程都会有不同的锁。Lock 对象应该全局创建,因为每个线程都应该能够查看同一锁是否被另一个线程持有。尝试将锁定对象创建移动为全局锁定!