在下面的代码中,每个进程(包括主进程(打印发生一次,因为如示例中所示,我有 2 个进程,语句打印 3 次。我希望它只运行一次,因为每个子进程应该只执行目标函数。
第二个问题,访问变量对我来说似乎不一致,因为我可以访问dic
变量并增加其值,但是尝试使用变量number
执行此操作时出现错误。
import concurrent.futures as cf
print("Not inside of the target funtion!")
num = 0
dic = {"X":1, "Y":0}
def target(n):
dic["X"] += 1
dic[n] = n
print(dic)
# print(dic["X"])
try:
print(num)
num += 1
except Exception as e:
print(e)
if __name__ == '__main__':
with cf.ProcessPoolExecutor(2) as ex:
ex.map(target, range(3))
print(dic)
# Output
# Not inside of the target funtion!
# Not inside of the target funtion!
# {'X': 2, 'Y': 0, 0: 0}
# local variable 'num' referenced before assignment
# {'X': 3, 'Y': 0, 0: 0, 1: 1}
# local variable 'num' referenced before assignment
# {'X': 4, 'Y': 0, 0: 0, 1: 1, 2: 2}
# local variable 'num' referenced before assignment
# Not inside of the target funtion!
# {'X': 1, 'Y': 0}
ex.map(target, range(3))
创建3个需要执行的任务。诚然,您只有 2 个进程来运行这些进程,因此第三个任务只需等待另一个任务完成即可运行。池中的进程是可重用的。这就是进程池的全部意义所在。进程池大小大于计算机上的处理器数是没有意义的,因为该数字最终决定了可以支持的多处理级别。
但是,对于每个进程执行,如@martineau所述,代码被重新导入,但测试if __name__ == '__main__'
失败。这就是为什么你看到"Not inside of the target funtion!"
打印了 3 次,但你不会进入一个循环,不断地启动 3 个新流程。
您需要在函数target
的开头插入一个global num
语句:
变量num
是一个全局变量。如果您所做的只是读取变量而不是在函数中修改它,则无需执行任何操作。否则,必须在函数中将其声明为global num
。您对dic
没有同样的问题,因为您没有修改dic
。dic
是一个引用,您正在修改dic
引用的内容,即字典中的键为"X"
的值。