Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在使用“经理”时如何使用“经理”;“繁殖”;_Python_Multiprocessing - Fatal编程技术网

Python 在使用“经理”时如何使用“经理”;“繁殖”;

Python 在使用“经理”时如何使用“经理”;“繁殖”;,python,multiprocessing,Python,Multiprocessing,这里有一些我正在做的伪代码 将多处理导入为mp 从多处理导入管理器 从TQM导入TQM def循环(arg): #做事 # ... results.append(result\u of_stuff) 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': 经理=经理() 结果=manager.list() 使用mp.get_context('spawn')。池(4)作为池: 列表(tqdm(pool.imap(loop,ls),total=len(ls))) #做

这里有一些我正在做的伪代码

将多处理导入为mp
从多处理导入管理器
从TQM导入TQM
def循环(arg):
#做事
# ...
results.append(result\u of_stuff)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
经理=经理()
结果=manager.list()
使用mp.get_context('spawn')。池(4)作为池:
列表(tqdm(pool.imap(loop,ls),total=len(ls)))
#做一些有结果的事情`
# ...
所以这里的问题是
循环
不知道
结果
。我有一个可行的方法,就是用“fork”代替“spawn”。但是我需要使用“spawn”的原因超出了我的问题范围

那么,我需要做什么最小的更改才能使其正常工作?我真的想保留
tqdm
,因此使用
imap

PS:我在Linux上

您可以使用它添加额外的参数:

import multiprocessing as mp
import os

from functools import partial
from multiprocessing import Manager

from tqdm import tqdm


def loop(results, arg):
    results.append(len(arg))


def main():
    ctx = mp.get_context("spawn")
    manager = Manager()
    l = manager.list()
    partial_loop = partial(loop, l)

    ls = os.listdir("/tmp")

    with ctx.Pool() as pool:
        results = list(tqdm(pool.imap(partial_loop, ls), total=len(ls)))

    print(f"Sum: {sum(l)}")


if __name__ == "__main__":
    main()
这种方法会产生一些开销,因为它会产生一个子进程来托管Manager服务器

由于您将在主流程中处理结果,因此我会这样做(但这当然取决于您的情况):

您可以使用添加额外的参数:

import multiprocessing as mp
import os

from functools import partial
from multiprocessing import Manager

from tqdm import tqdm


def loop(results, arg):
    results.append(len(arg))


def main():
    ctx = mp.get_context("spawn")
    manager = Manager()
    l = manager.list()
    partial_loop = partial(loop, l)

    ls = os.listdir("/tmp")

    with ctx.Pool() as pool:
        results = list(tqdm(pool.imap(partial_loop, ls), total=len(ls)))

    print(f"Sum: {sum(l)}")


if __name__ == "__main__":
    main()
这种方法会产生一些开销,因为它会产生一个子进程来托管Manager服务器

由于您将在主流程中处理结果,因此我会这样做(但这当然取决于您的情况):


我知道你已经接受了答案,但让我加上我的“两分钱”:

解决问题的另一种方法是使用全局变量
results
初始化池中的每个进程。问题是,当使用
spawn
时,新创建的进程不会继承主进程的地址空间(其中包括
结果的定义)。相反,执行从程序的顶部开始。但是创建
results
的代码永远不会执行,因为
if\uuuuuu name\uuuuu='\uuuuu main\uuuu'
检查。但这是一件好事,因为无论如何,您都不需要此列表的单独实例

那么,我们如何在所有流程中共享全局变量
结果的相同实例呢?这是通过使用池初始值设定项实现的,如下所示。此外,如果您想要一个准确的进度条,您应该真正使用
imap\u unordered
而不是
imap
,以便进度条按照任务完成顺序而不是按照任务提交的顺序进行更新。例如,如果提交的第一个任务恰好是最后一个要完成的任务,那么使用
imap
将导致进度条在所有任务完成之前不会继续,然后它将一次命中100%

但请注意:imap_unordered
的doumentation仅说明结果将以任意顺序返回,而不是以完成顺序返回。但是,当使用chunksize参数1时(如果未明确指定,则为默认值),结果将按完成顺序返回。如果您不想依赖于此,请改用
apply\u async
指定一个将更新progrss栏的回调函数。请参见最后一个代码示例

将多处理导入为mp
从多处理导入管理器
从TQM导入TQM
def初始_池(_结果):
全球成果
结果=_结果
def循环(arg):
导入时间
#做事
# ...
时间。睡眠(1)
结果。追加(arg**2)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
经理=经理()
结果=manager.list()
ls=列表(范围(1,10))
使用mp.get_context('spawn').Pool(4,initializer=init_Pool,initargs=(results,))作为池:
列表(tqdm(pool.imap_无序(循环,ls),总计=len(ls)))
打印(结果)
更新:另一种(更好)方式

将多处理导入为mp
从TQM导入TQM
def循环(arg):
导入时间
#做事
# ...
时间。睡眠(1)
返回参数**2
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
结果=[]
ls=列表(范围(1,10))
使用mp.get_context('spawn')。池(4)作为池:
以tqdm(总=len(ls))作为pbar:
对于池中的v。imap_无序(循环,ls):
结果.追加(五)
pbar.update(1)
打印(结果)
更新:最安全的方式

将多处理导入为mp
从TQM导入TQM
def循环(arg):
导入时间
#做事
# ...
时间。睡眠(1)
返回参数**2
def my_回调(v):
结果.追加(五)
pbar.update(1)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
结果=[]
ls=列表(范围(1,10))
使用mp.get_context('spawn')。池(4)作为池:
以tqdm(总=len(ls))作为pbar:
对于ls中的arg:
apply_async(循环,args=(arg,),callback=(my_callback))
pool.close()
pool.join()
打印(结果)

我知道你已经接受了答案,但让我加上我的“两分钱”:

解决问题的另一种方法是使用全局变量
results
初始化池中的每个进程。问题是,当使用
spawn
时,新创建的进程不会继承主进程的地址空间(其中包括
结果的定义)。相反,执行从程序的顶部开始。但是创建
results
的代码永远不会执行,因为
if\uuuuuu name\uuuuu='\uuuuu main\uuuu'
检查。但这是一件好事,因为无论如何,您都不需要此列表的单独实例

那么,我们如何在所有流程中共享全局变量
结果的相同实例呢?这是通过使用池初始值设定项实现的,如下所示。此外,如果您想要一个准确的进度条,您应该真正使用
imap\u unordered
而不是
imap
,这样进度条将按任务完成顺序而不是按任务完成顺序更新