在下面的代码中,每个流程(包括主流程)都进行一次打印,因为如示例中所示,我有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个新流程的循环的原因。
您需要在函数global num
的开头插入target
语句:
Variable num
是全局变量。如果您要做的只是读取变量而不是在函数中修改变量,则无需执行任何操作。否则,必须在函数中将其声明为global num
。由于您没有修改dic
,因此dic
没有相同的问题。 dic
是参考,您正在修改dic
所指的内容,即字典中键为"X"
的值。