Python多进程从不加入

2 投票
1 回答
3206 浏览
提问于 2025-04-17 12:49

我在使用 multiprocessing,具体来说是用 Pool 来开启几个“线程”,处理一些比较慢的任务。不过,有个问题,我发现主线程无法重新加入,即使所有的子线程看起来都已经结束了。

解决方案:这个问题的答案是直接启动多个 Process 对象,而不是使用 Pool。虽然原因不是特别清楚,但我猜剩下的进程是池的管理者,它在子进程完成后并没有结束。如果其他人也遇到这个问题,这就是答案。


主线程

pool = Pool(processes=12,initializer=thread_init)
for x in xrange(0,13):
    pool.apply_async(thread_dowork)
pool.close()
sys.stderr.write("Waiting for jobs to terminate\n")
pool.join()

xrange(0,13) 的数字比进程数量多一个,因为我觉得可能有一个进程没有被分配到任务,所以没有结束,我想强制它去接一个任务。我也试过用12这个数字。

多进程函数

def thread_init():
    global log_out
    log_out = open('pool_%s.log'%os.getpid(),'w')
    sys.stderr = log_out
    sys.stdout = log_out
    log_out.write("Spawned")
    log_out.flush()
    log_out.write(" Complete\n")
    log_out.flush()


def thread_dowork():
    log_out.write("Entered function\n")
    log_out.flush()
    #Do Work
    log_out.write("Exiting ")
    log_out.flush()
    log_out.close()
    sys.exit(0)

所有12个子进程的日志输出是:

Spawned
Complete
Entered function
Exiting

主线程打印“等待任务结束”,然后就一直在那里停着。

top 只显示了一个脚本的副本(我认为是主线程)。而 htop 显示了两个副本,其中一个是来自 top 的,另一个则是其他的。根据它的PID,那个也不是任何一个子进程。

有没有人知道我不知道的事情?

1 个回答

1

我没有确切的答案,但我看了下Apply_async的文档,感觉它和你说的问题有点矛盾...

回调函数应该立即完成,否则处理结果的线程会被阻塞。

我对Pool不太熟悉,但我觉得你的需求可以很容易地通过这个Python每周模块上的方法来解决。

撰写回答