【问题标题】:why does multiprocessing create a clone for base variables for each thread为什么 multiprocessing 为每个线程创建一个基变量的克隆
【发布时间】:2023-02-10 03:45:03
【问题描述】:
所以我正在使用具有 3 个线程的多处理池来运行一个完成特定工作的函数,并且我在该函数外部定义了一个等于 0 的变量,并且每次该函数完成它的工作时它应该将 1 添加到该变量并且打印它,但每个线程都使用一个单独的变量
这是代码:
from multiprocessing import Pool
number_of_doe_jobs = 0
def thefunction():
global number_of_doe_jobs
# JOB CODE GOES HERE
number_of_doe_jobs+=1
if __name__ =="__main__":
p = Pool(3)
p.map(checker, datalist)
所需的输出是将 1 添加到 number_of_doe_jobs ,
但是每个线程都将 1 添加到它自己的 number_of_doe_jobs ,所以现在有 3 个 number_of_doe_jobs 变量。
【问题讨论】:
标签:
python
multithreading
multiprocessing
【解决方案1】:
您没有生成 3 个线程。您正在生成 3 个进程。每个进程都有自己的内存空间,有自己的解释器副本和自己独立的对象空间。全局变量不跨进程共享。有一些方法可以创建共享变量(通过套接字进行通信),但使用 multiprocessing.Queue 可能会更好。在主线代码中创建它,并将其作为参数传递给子流程。让作业在队列上推送一个“完成”标志,并让主线代码读取结果。
跟进
NUMBER 个工作将始终等于len(datalist),因此不清楚您为什么要跟踪它。在这里,我创建了一个多处理队列并将其传递给函数。 Python 通过创建套接字来实现它。检查器函数在完成时发送一个信号,主线代码获取每一个并打印它。 q.get 将阻塞直到队列中有内容。
import multiprocessing
def checker(q):
# JOB CODE GOES HERE
q.put( "done" )
if __name__ =="__main__":
q = multiprocessing.Queue()
p = Pool(3)
p.map(lambda: checker(q), datalist)
for _ in datalist:
print( q.get() )