【问题标题】:Why doesn't it has 0 as its output when I'm using threading.Lock to lock thread actions?当我使用 threading.Lock 锁定线程操作时,为什么它的输出没有 0?
【发布时间】:2020-05-28 19:33:21
【问题描述】:
import threading

COUNTER = 100000

lock = threading.Lock()

def add():
  global x
  with lock:
    for i in range(COUNTER):
      x += 1

def subtract():
  global x
  with lock:
    for i in range(COUNTER):
      x -= 1
x = 0
t0 = threading.Thread(target = add)
t1 = threading.Thread(target = subtract)
t0.start()
t1.start()
print(x)
# The output shall be zero isn't it?

我根据我在课程中看到的代码编写了这段代码,但实际上效果并不好。共享变量时,线程对数据的处理非常错误

【问题讨论】:

    标签: python multithreading python-3.8 locks


    【解决方案1】:

    更正后的代码是:

    import threading
    
    COUNTER = 100000
    
    lock = threading.Lock()
    
    
    def add():
        global x
        with lock:
            for i in range(COUNTER):
                x += 1
    
    
    def subtract():
        global x
        with lock:
            for i in range(COUNTER):
                x -= 1
    
    
    x = 0
    t0 = threading.Thread(target=add)
    t1 = threading.Thread(target=subtract)
    t0.start()
    t1.start()
    # Added the below lines
    t0.join() 
    t1.join()
    # END
    print(x)
    

    您的错误原因是您的主线程没有等待您的子线程完成那里的进程。这就是为什么在打印介于两者之间的 x 值时会得到异常输出的原因。

    【讨论】:

    • 所以即使线程被锁定以访问数据,我们仍然必须加入它们?我看到这是可行的,但是在我看到的地方,那个人没有使用 join() 方法...无论如何,感谢您的解决方案。
    • 锁基本上是用来阻止一个变量同时被多个线程访问,直到一个线程释放它。 join 方法是等待子线程进程完成。
    • 嗯,非常感谢您的解释。我知道了,我将通过练习获得线程行为。也许python的版本影响了我观看的那个人的结果,所以我没有得到相同的结果(他使用的是旧版本)。
    猜你喜欢
    • 2018-10-19
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-17
    • 1970-01-01
    • 2023-01-17
    • 1970-01-01
    相关资源
    最近更新 更多