python - python 多处理函数返回多个输出

标签 python windows-7 multiprocessing

我正在尝试使用多重处理来返回一个列表,但我不是等到所有进程都完成,而是从 mp_factorizer 中的一个返回语句中获得多个返回,如下所示:

None
None
(returns list)

在此示例中我使用了 2 个线程。如果我使用 5 个线程,则在列表发布之前将有 5 个 None 返回。这是代码:

def mp_factorizer(nums, nprocs, objecttouse):
    if __name__ == '__main__':
        out_q = multiprocessing.Queue()
        chunksize = int(math.ceil(len(nums) / float(nprocs)))
        procs = []
        for i in range(nprocs):
            p = multiprocessing.Process(
                    target=worker,                   
                    args=(nums[chunksize * i:chunksize * (i + 1)],
                          out_q,
                    objecttouse))
            procs.append(p)
            p.start()

        # Collect all results into a single result dict. We know how many dicts
        # with results to expect.
        resultlist = []
        for i in range(nprocs):
            temp=out_q.get()
            index =0
            for i in temp:
                resultlist.append(temp[index][0][0:])
                index +=1

        # Wait for all worker processes to finish
        for p in procs:
            p.join()
            resultlist2 = [x for x in resultlist if x != []]
        return resultlist2

def worker(nums, out_q, objecttouse):
    """ The worker function, invoked in a process. 'nums' is a
        list of numbers to factor. The results are placed in
        a dictionary that's pushed to a queue.
    """
    outlist = []
    for n in nums:        
        outputlist=objecttouse.getevents(n)
        if outputlist:
            outlist.append(outputlist)   
    out_q.put(outlist)

mp_factorizer 获取项目列表、线程数以及工作线程应使用的对象,然后拆分项目列表,以便所有线程获得相同数量的列表,并启动工作线程。 然后,工作人员使用该对象从给定列表中计算某些内容,并将结果添加到队列中。 Mp_factorizer 应该从队列中收集所有结果,将它们合并到一个大列表中并返回该列表。然而 - 我得到了多次返回。

我做错了什么?或者这是由于 Windows 处理多处理的奇怪方式造成的预期行为? (Python 2.7.3、Windows7 64位)

编辑: 问题是 if __name__ == '__main__': 的位置错误。我在解决另一个问题时发现,请参阅using multiprocessing in a sub process以获得完整的解释。

最佳答案

if __name__ == '__main__'是在错误的地方。一个快速修复方法是仅保护对 mp_factorizer 的调用,如 Janne Karila 建议的那样:

if __name__ == '__main__':
    print mp_factorizer(list, 2, someobject)

但是,在 Windows 上,主文件将在执行时执行一次 + 每个工作线程执行一次,在本例中为 2。因此,这将是主线程的总共 3 次执行,不包括代码的 protected 部分。

一旦在同一主线程中进行其他计算,这可能会导致问题,并且至少会不必要地降低性能。尽管只有工作函数应该执行多次,但在 Windows 中,不受 if __name__ == '__main__' 保护的所有内容都将被执行。 .

所以解决方案是通过仅在之后执行所有代码来保护整个主进程 if __name__ == '__main__' .

但是,如果辅助函数位于同一个文件中,则需要将其从该 if 语句中排除,否则无法多次调用它以进行多处理。

伪代码主线程:

# Import stuff
if __name__ == '__main__':
    #execute whatever you want, it will only be executed 
    #as often as you intend it to
    #execute the function that starts multiprocessing, 
    #in this case mp_factorizer()
    #there is no worker function code here, it's in another file.

即使整个主进程受到保护,工作函数仍然可以启动,只要它在另一个文件中。

伪代码主线程,带有辅助函数:

# Import stuff
#If the worker code is in the main thread, exclude it from the if statement:
def worker():
    #worker code
if __name__ == '__main__':
    #execute whatever you want, it will only be executed 
    #as often as you intend it to
    #execute the function that starts multiprocessing, 
    #in this case mp_factorizer()
#All code outside of the if statement will be executed multiple times
#depending on the # of assigned worker threads.

有关可运行代码的详细说明,请参阅 using multiprocessing in a sub process

关于python - python 多处理函数返回多个输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14583025/

相关文章:

python - 检查 Python multiprocessing.Connection 的实例?

python - OpenCV 车辆检测

c# - 将现有服务引用添加到新解决方案中的新项目

python - 使用 SQLAlchemy 和多处理卡在 Python 脚本中

multithreading - 只有多处理还是单个进程的多线程也使用多核?

python - Scikit-learn χ²(卡方)统计量和相应的列联表

python - pysvn 1.6.3 可以在 linux 下与 Subversion 1.6 一起工作吗?

winapi - 更改任务栏组的图标(Win7)

windows-7 - 检查 InnoSetup 配置文件的 [Run] 段中的 Windows 版本

Python 多处理 : Handling Child Errors in Parent