【问题标题】:python : multiprocessing managamentpython:多处理管理
【发布时间】:2012-12-05 14:53:00
【问题描述】:

使用多处理 python 库,我可以启动多进程,例如

import multiprocessing as mu

def worker(n)
        print "worker:", n
        n = int(1e4)
        for i in range(n):
                for j in range(n):
                        i*j 
        return

if __name__ == '__main__':
        jobs = []
        for i in range(5):
                p = mu.Process(target=worker, args=(i,))
                jobs.append(p)
                p.start()

我可以通过

获得处理器(cpu核心)的数量
np = mu.cpu_count()

但是,如果我有一个进程列表,我如何才能在不对处理器过度充电的情况下启动?
如果我有一个四核,我如何启动前 4 个进程?并在完成一个进程时启动其他进程。

参考文献

【问题讨论】:

    标签: python multiprocessing cpu-cores


    【解决方案1】:

    我建议绕过问题并使用multiprocessing.Poolexampleapi)。

    (根据文档中的示例修改)

    from multiprocessing import Pool
    
    def f(x):
        return x*x
    
    if __name__ == '__main__':
        num_proc = multiprocessing.cpu_count()
        pool = Pool(processes=num_proc)
        res = pool.map(f, range(10))
    

    或者,您可以设置生产者/消费者方案并拥有固定数量的长时间运行的子流程。

    第三种真正快速而肮脏的方法是使用mu.Queue。请注意,get 会阻塞,直到它返回结果。

    import multiprocessing as mu
    import time
    res = mu.Queue()
    
    def worker(n):
        print "worker:", n
        time.sleep(1)
        res.put(n)
        return
    
    if __name__ == '__main__':
        jobs = []
        np = mu.cpu_count()
        print np
        # start first round
        for j in range(np):
            p = mu.Process(target=worker, args=(j,))
            jobs.append(p)
            p.start()
        # every time one finishes, start the next one
        for i in range(np,15):
            r = res.get()
            print 'res', r
            p = mu.Process(target=worker, args=(i,))
            jobs.append(p)
            p.start()
        # get the remaining processes 
        for j in range(np):
            r = res.get()
            print 'res', r
    

    【讨论】:

    • 我知道pool.map 但我的问题更多的是,如何管理套流程?也许与.is_alive()
    • docsprocesses 关键字这么说:“如果 processesNone,则使用 cpu_count() 返回的数字”所以你对 @987654335 的建议@ 是默认情况下发生的情况。
    • @martineau 很公平,但把事情说清楚从来没有什么坏处(我被系统/版本之间不同的默认行为所困扰(主要是matplotlib 样式))
    【解决方案2】:

    我做这个解决方案

    import multiprocessing as mu
    
    def worker(n):
            print "worker:", n
            n = int(1e4/2)
            for i in range(n):
                    for j in range(n):
                            i*j
            return
    
    if __name__ == '__main__':
            jobs = []
            for i in range(5):
                    p = mu.Process(target=worker, args=(i,))
                    jobs.append(p)
    
            running = []
            np = mu.cpu_count()
    
            for i in range(np):
                    p = jobs.pop()
                    running.append(p)
                    p.start()
    
            while jobs != []:
                    for r in running:
                            if r.exitcode == 0:
                                    running.remove(r)
                                    p = jobs.pop()
                                    p.start()
                                    running.append(p)
    

    【讨论】:

    • 我认为您将在最后一个 np 进程完成之前将其杀死。清空jobs后,主进程将完成,不会等待子进程完成。
    猜你喜欢
    • 1970-01-01
    • 2018-01-13
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 2013-07-06
    • 2013-06-18
    • 2022-01-21
    • 2023-04-05
    相关资源
    最近更新 更多