Tensorflow的Python多处理工作者队列

时间:2019-12-04 06:37:25

标签: python

Tensorflow可以运行很长时间的培训,并且可能在刷新页面之间使服务器崩溃。

我希望可以使用上一个答案中的以下内容来解决此问题:

我有一个python函数,必须总共运行12次。我目前已进行此设置,以使用多处理库中的Pool并行运行所有这些库。通常我一次运行6次,因为该函数占用大量CPU资源,并且并行运行12次通常会导致程序崩溃。当我们一次执行6个时,第二组6将不会开始,直到所有前6个过程都完成为止。理想情况下,我们希望在最初一批6个中的一个完成后再启动另一个(例如第7个),以便6个同时运行,同时还有更多要开始的时间。现在,代码看起来像这样(它将被调用两次,将一个列表中的前6个元素传递给另一个列表,然后将另一个6个元素传递给另一个列表:

from multiprocessing import Pool

def start_pool(project_list):

    pool = Pool(processes=6)
    pool.map(run_assignments_parallel,project_list)

因此,我一直在尝试实现工作程序/队列解决方案,并遇到了一些问题。我有一个看起来像这样的工作函数:

def worker(work_queue, done_queue):
    try:
        for proj in iter(work_queue.get, 'STOP'):
            print proj
            run_assignments_parallel(proj)
            done_queue.put('finished ' + proj )
    except Exception, e:        
        done_queue.put("%s failed on %s with: %s" % (current_process().name, proj,        e.message))
    return True

调用worker函数的代码如下:

workers = 6
work_queue = Queue()
done_queue = Queue()  
processes = []
for project in project_list:
    print project
    work_queue.put(project)
for w in xrange(workers):        
    p = Process(target=worker, args=(work_queue, done_queue))
    p.start()
    processes.append(p)
    work_queue.put('STOP')
for p in processes:
     p.join()    
     done_queue.put('STOP')
for status in iter(done_queue.get, 'STOP'):        
    print status

project_list只是功能run_assignments_parallel中需要运行的12个项目的路径的列表。

现在的编写方式是,对于同一进程(项目),该函数被多次调用,我无法真正知道发生了什么。这段代码基于我发现的一个示例,我很确定循环结构被弄乱了。任何帮助都将是巨大的,我对此事的无知深表歉意。谢谢!


这似乎可以运行路径,例如内部带有python的文件名,我希望将其放置在我的django服务器的视图路径中,并使其在tensorflow培训课程中运行

1 个答案:

答案 0 :(得分:0)

这是一个由您的摘录制作的最小运行示例。我已将您的代码转换为Python 3,因为不推荐使用Python 2,并且不应使用该版本编写新代码。

from multiprocessing import Process
from multiprocessing.process import current_process
from queue import Queue


def worker(work_queue, done_queue):
    proj=None
    try:
        for proj in iter(work_queue.get, 'STOP'):
            print(current_process().name, "#", proj)
            done_queue.put('finished ' + proj )
    except Exception as e:
        done_queue.put("%s failed on %s with: %s" % (current_process().name, proj, e.args))
    print(current_process().name, "#", "Quit")
    return True

def main():
    workers = 6
    work_queue = Queue()
    done_queue = Queue()
    processes = []
    project_list = list("ab")
    for project in project_list:
        work_queue.put(project)
    for w in range(workers):
        p = Process(target=worker, args=(work_queue, done_queue))
        p.start()
        processes.append(p)
        work_queue.put('STOP')
    for p in processes:
        p.join()
        done_queue.put('STOP')
    for status in iter(done_queue.get, 'STOP'):
        print(status)

if __name__ == '__main__':
    main()
Process-1 # a
Process-1 # b
Process-2 # a
Process-2 # b
Process-2 # Quit
Process-3 # a
Process-3 # b
Process-3 # Quit
Process-4 # a
Process-4 # b
Process-4 # Quit
Process-5 # a
Process-5 # b
Process-5 # Quit
Process-6 # a
Process-6 # b
Process-6 # Quit

如您所见,每个项目在每个工作程序中处理。 但是,主进程在加入进程时挂起,因为Process-1永不终止... 我认为这是由于iter(work_queue.get, 'STOP')通话造成的,我不明白您试图在此实现什么。

您使用队列的方式对我来说似乎很奇怪。 我建议您更深入地阅读queue模块文档,尤其是task_done方法,该文档必须与get结合使用。

最后,为什么您不坚持我认为最适合您的问题的Pool解决方案。 池将自动处理等待队列,并确保尽可能多(6)个工人同时运行。