【发布时间】:2020-12-04 11:46:21
【问题描述】:
我正在努力使用 Python“多处理”模块。我想用简单的东西填充队列并在队列不为空时打印东西,这会让我知道我的一个进程已终止。
您会在下面找到一个最小的示例:
-
我创建了一个空队列
q -
我创建了一个进程列表
processes,只要我的 CPU 允许我就可以;我一创建就启动列表中的每个进程 (proc.start()) -
每个进程的目标函数是一个很简单的函数
f,它先等待2秒,然后在队列中写入'hello'(这是它唯一的参数) -
之后,我每 0.5 秒检查一次
q是否不为空(每当我的一个进程成功执行函数f时,它应该收到一个“你好”),并且我还检查我的进程是否处于活动状态或不是。
我在这里面临两个问题:
- 从第一次尝试开始,我的所有进程都不活着;
- 从未打印任何内容,这意味着队列
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,因为“打印”行从未执行(因此队列为空)。
【问题讨论】:
-
控制台打印了什么?
-
@JeffUK 我编辑了我的帖子以详细说明。
-
你是否有机会在 IDLE 中运行它?
-
related :*.com/questions/18204782/… 似乎在 IDLE 上,子进程没有机会将运行时错误打印到控制台,所以你什么都看不到,但在其他环境中你将根据此链接获得运行时错误。
-
我正在使用 Spyder 运行我的代码。我解决了这个问题,请参阅下面我自己的答案,这是因为我的主要代码块没有被 if name == 'main' “保护”