concurrent.futures库中ProcessPoolExecutor的奇怪行为

2024-07-07 07:20:51 发布

您现在位置:Python中文网/ 问答频道 /正文

在下面的代码中,每个进程(包括主进程)打印一次,如示例中所示,我有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}

Tags: ofthetarget进程localasnotvariable
1条回答
网友
1楼 · 发布于 2024-07-07 07:20:51

ex.map(target, range(3))创建需要执行的3任务。如果您只有两个进程来运行这些任务,那么第三个任务只需等待另一个任务完成后才能运行。池中的进程是可重用的。这就是进程池的全部要点。进程池大小大于计算机上的处理器数量没有意义,因为这个数量最终决定了可以支持的多处理级别

然而,对于每个进程执行,正如@martineau所说的,代码被重新导入,但是测试if __name__ == '__main__'失败。这就是为什么你看到"Not inside of the target funtion!"打印了3次,但你没有进入一个循环不断地启动3个新进程

您需要在函数target的开头插入global num语句:

变量num是一个全局变量。如果您所做的只是读取变量而不是在函数中修改它,则不需要执行任何操作。否则,必须在函数中声明它为global num。因为您没有修改dic,所以您对dic没有相同的问题dic是一个引用,您正在修改dic引用的内容,即字典中键为"X"的值

相关问题 更多 >