【问题标题】:Python threading Lock not working in simple examplePython线程锁在简单示例中不起作用
【发布时间】:2014-09-29 16:04:23
【问题描述】:

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

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)

输出:

1 here!
2 here!
2 leaving!
1 leaving!
1352010

正如您所见,两个线程都进入了应该同时锁定的部分,因此全局变量“some_var”的增量被混淆了。

看起来 Lock 由于某种原因无法正常工作。 对于高达 10000 的范围,它可以工作,但这可能只是因为在如此短的计算期间没有释放 GIL。

发生了什么事?

我使用的是 Python3.3.2 64bit

【问题讨论】:

    标签: python multithreading locking python-multithreading


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        或者你可以在你的 main() 函数中定义锁。并将其传递给被调用的函数。

        lock = threading.Lock()
        t1 = Thread(target=some_func, args=(1,lock))
        t2 = Thread(target=some_func, args=(2,lock))
        t1.start()
        t2.start()
        

        这样只有一把锁。最好尽可能避免使用全局变量。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-01
          • 2015-11-23
          • 2016-03-02
          • 1970-01-01
          相关资源
          最近更新 更多