python - 多次调用后,Python 子进程模块管道停止使用 Apache Beam
问题描述
我正在使用 python 子进程模块从 MacOS 上的 Apache Beam DoFn 运行子进程。
前几个子进程调用工作正常,但是在大约第 7 个子进程调用时,我开始收到错误:
OSError: [Errno 9] Bad file descriptor
从子流程模块中。
我尝试更改正在读取/管道的文件,但这不会影响产生的错误。
我尝试将问题隔离到以下代码,但这运行正常:
import apache_beam as beam
from apache_beam.options.pipeline_options import PipelineOptions
from subprocess import run, PIPE
import io
def run_subprocess(element):
x = run(["ffmpeg", "-loglevel", "panic", "-t", '900', "-f", "mp3", "-i", "pipe:0", "-map_metadata", "-1", "-vn", "-acodec", 'pcm_s16le', "-ac",
'2', "-ar", '44100', "-f", "wav", 'pipe:1'], input=element.read(), capture_output=True)
yield x.stdout[:20]
def open_file(element):
with open(element, 'rb') as f:
data = io.BytesIO(f.read())
data.seek(0)
yield data
with beam.Pipeline(options=PipelineOptions()) as p:
_ = (p
| "A" >> beam.Create(['./test.mp3']*100)
| "B" >> beam.ParDo(open_file)
| "C" >> beam.ParDo(run_subprocess)
| "D" >> beam.ParDo(print)
)
与上面的示例相比,管道相对复杂,但失败的特定 DoFn 与run_subprocess
上面非常相似。
我已经尝试在OSError
那里捕获并设置测试子流程模块的其他用途。那时,即使只是运行subprocess.run(['echo'], input=b'hi', capture_output=True)
或Popen(['echo'], stdout=PIPE, stderr=PIPE, stdin=PIPE)
引发相同的错误。但是,在Popen(['echo'])
没有管道的情况下运行不会导致任何问题。
知道这里发生了什么吗?Apache Beam 使用的管道和子进程使用的管道之间是否存在一些干扰?或者也许对管道使用/缓冲区大小有一些系统级别的限制?
解决方案
推荐阅读
- javascript - 将 HTML 编码为有效的 JSON
- python - Celery - 我应该为 Windows 繁重的 cpu 进程和 redis 后端使用什么池来进行状态跟踪?
- linux - 在 Linux 中静默安装 PowerShell 模块 /quiet
- python - Seaborn 如何在 catplot 或 pointplot 中使用关键字参数
- python-3.x - 无法访问 API
- javascript - 如何为创建的每个随机生成的对象创建随机 X 和 Y 旋转(三个 JS)
- python - 在两个 numpy 数组中乘以“交叉”
- react-native - Xamarin.Forms/React Native 是否也有类似 Flutter 的“配置文件”模式?
- javascript - MUI - makeStyles - 无法读取未定义的属性
- python - Matplotlib 错误:x 和 y 必须具有相同的第一维,但形状为 (100,) 和 (449,)