🐛 fix(av1-transfer): silently fall back when preexec_fn exec fails in multithreaded context

GIL contention after fork in ThreadPoolExecutor can cause os.execvp to fail.
Catch the exception so subprocess proceeds with its own exec, keeping
transcoding functional even if process renaming fails.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
FlintyLemming
2026-02-28 11:42:57 +08:00
parent 79e19229af
commit 94890d6418

View File

@@ -132,15 +132,19 @@ def transcode_one_file(file_info, overall_bar, slot_bars, slot_queue, process_na
str_args = [str(a) for a in ffmpeg_args]
if process_name:
# fork 后、subprocess 执行 exec 之前用 os.execvp 替换进程
# - execvp 通过 PATH 查找 ffmpeg规避 execve 直接调用 symlink 的问题)
# - argv[0] 设为别名ps/top 显示别名而非 ffmpeg
# - subprocess 设好的 stdout/stderr pipe 已继承,无需额外处理
# 尝试在 fork 后、subprocess exec 之前用 os.execvp 替换进程(设 argv[0] 为别名)
# 多线程环境下 GIL 可能导致 execvp 失败;失败时静默返回,
# subprocess 会接着正常执行 ffmpeg转码不受影响
_pname = process_name
_args = str_args
def _try_exec():
try:
os.execvp("ffmpeg", [_pname] + _args)
except Exception:
pass
proc = subprocess.Popen(
["ffmpeg"] + str_args,
preexec_fn=lambda: os.execvp("ffmpeg", [_pname] + _args),
preexec_fn=_try_exec,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)