我很难使用Python的“多处理”模块。我希望用简单的东西填充队列,并在队列不为空时打印内容,这将使我知道我的一个进程已经结束。
下面是一个很小的例子:
qprocesses ),只要我的CPU允许,我就会立即启动列表中的每个进程(proc.start())。f,它首先等待2秒,然后在队列中写“hello”(这是它的唯一参数)。q不是空的(每当我的一个进程成功地执行f函数时,它都会收到一个“hello”),我还会检查我的进程是否处于活动状态。我在这里面临两个问题:
q从未成功地接收到任何“hello”。你会在下面找到我的代码。
# -*- coding: utf-8 -*-
"""
Created on Fri Dec 4 12:21:23 2020
@author: rbourgeon
"""
import multiprocessing as mp
import time
def f(q):
time.sleep(2)
q.put('hello')
pool_size = mp.cpu_count() - 1
print(f'pool_size is {pool_size}')
q = mp.Queue()
processes = []
num_active_processes = 0
# Starting processes
while len(processes) < pool_size:
proc = mp.Process(target=f,
args=(q,)
)
processes.append(proc)
proc.start()
print(f'{len(processes)} jobs started')
num_active_processes += 1
# Checking if queue is empty every 0.5 second. If not empty, we pop an element
# and we print it
for i in range(1, 100):
print(f'\nAttempt #{i}')
if not q.empty():
print(q.get())
time.sleep(0.5)
print(processes)
print([p.is_alive() for p in processes])以下内容将打印到控制台:
pool_size is 7
1 jobs started
2 jobs started
3 jobs started
4 jobs started
5 jobs started
6 jobs started
7 jobs started
Attempt #1
[<Process(Process-8, stopped[1])>, <Process(Process-9, stopped[1])>, <Process(Process-10, stopped[1])>, <Process(Process-11, stopped[1])>, <Process(Process-12, stopped[1])>, <Process(Process-13, stopped[1])>, <Process(Process-14, stopped[1])>]
[False, False, False, False, False, False, False]
Attempt #2
[<Process(Process-8, stopped[1])>, <Process(Process-9, stopped[1])>, <Process(Process-10, stopped[1])>, <Process(Process-11, stopped[1])>, <Process(Process-12, stopped[1])>, <Process(Process-13, stopped[1])>, <Process(Process-14, stopped[1])>]
[False, False, False, False, False, False, False]等等直到最后一次尝试。
这意味着( a)我的所有进程都在0.5秒( b)内死亡),同时,没有一个进程成功地执行函数f,因为"print“行从未执行过(因此队列是空的)。
发布于 2020-12-04 12:07:17
我发现了我的代码不能按预期工作的原因:启动进程的代码块if __name__ == '__main__':.应该封装在中
应该使用
if __name__ == '__main__':保护程序的“入口点”。
这样做,代码工作正常。
发布于 2020-12-04 12:01:04
您的f函数不会输入任何作为工作人员运行的内容:一旦它运行最后一行,它就会结束并返回--这将关闭它所驻留的进程。
因此,预计在您的最后检查中不会有任何进程处于活动状态。
令人惊讶的是,您说调用方队列中没有显示该值--正如您所发现的,这是因为在Windows中,与启动子进程调用本身有关的代码只应该在主进程上运行(其方法是检查__name__变量是否等于"__main__") --实际上,您可能没有看到打印结果。我在这里运行了您的代码,它的工作原理与预期一样。请注意,您只需在每次“尝试”中打印一个队列元素。因为每个进程只会在队列中放置一个元素并退出,所以在前15次尝试中的8次之后(前4次尝试将在子进程处于2秒的“睡眠”中)之后打印出来,并且当进程结束时,不会看到后续打印。
如果您想让工作人员继续运行,那么您的目标函数中应该有一个while循环,它将尝试从队列和分派任务中读取消息。编写它并不难,但是Python已经在concurrent.futures库中为您完成了这一点:是的,使用这种方法,您可以创建一个由Python运行时保持活动的子进程池,而不是显式关闭它,并且可以在任何时候从主进程单独调用每个目标函数,重用该进程--而且该函数只是一个普通的Python函数--不需要循环、侦听队列等等…
https://stackoverflow.com/questions/65143003
复制相似问题