提问人:Anis Smail 提问时间:11/18/2023 最后编辑:quamranaAnis Smail 更新时间:11/18/2023 访问量:42
为什么当我添加 thread.join() 时,这个多线程代码的行为更安全?
Why this multi-threaded code behaves in a safer way when I add thread.join()?
问:
import threading
# Shared variable
shared_variable = 0
NUM_THREADS = 999
NUM_INCREMENT = 1_000_000
# Function to increment the shared variable
def increment():
global shared_variable
for _ in range(NUM_INCREMENT):
shared_variable += 1
# Creating multiple threads to increment the shared variable concurrently
threads = []
for _ in range(NUM_THREADS):
thread = threading.Thread(target=increment)
threads.append(thread)
for thread in threads:
thread.start()
for thread in threads:
thread.join()
# Display the value of the shared variable after concurrent increments
print(
f"The value of the shared variable is: {shared_variable}, expected : {NUM_THREADS * NUM_INCREMENT}"
)
当我加入线程时,此代码始终打印预期的数字。但是,如果我注释此代码,则某些增量会失败(这是我实际期望的结果!
# for thread in threads:
# thread.join()
为什么当我添加连接时,此代码以线程安全的方式运行?
答:
thread.join()
等待完成其工作。如果你要求某人做某事,你会立即抱怨他们没有把工作做好吗?或者你会等到他们完成工作后再做出判断?thread
如果程序在打印值 之前调用每个线程,则线程有时间完成其工作。如果它没有加入线程,并且您在启动线程后立即打印,那么......你得到你得到的任何东西。thread.join()
shared_variable
shared_variable
当您注释掉执行所有调用的循环时会发生什么情况,这与您确实有联接时非常相似:thread.join()
您的代码将难以执行在每个线程上调用的循环。这是因为一旦启动了多个线程,它们都倾向于相互阻塞,包括主线程。所有的线程都将缓慢运行,相互竞争,情况越来越糟。thread.start()
我尝试了没有连接的版本,最后一行是这样打印的:
The value of the shared variable is: 997692304, expected : 999000000
这意味着主线程在启动所有线程时非常慢,以至于当主线程退出启动循环并以最终 .print()
如此多的线程完成的原因是它们执行的操作很少(只是增加一个数字),而主线程正在调用,它正在执行更复杂和耗时的事情。thread.start()
相反,在代码完好无损的情况下,调用所有方法意味着主线程将故意等待所有线程完成。这保证了全局变量将具有您期望的所有增量。thread.join()
评论
.join()
print()