Hunting Down a Zombie Python Thread: My First PR to Webots
Описание и применение
Проблема: скрипты Python в Webots на Windows не завершаются, оставляя «зомби» процессы. Решение: сделать вспомогательный поток демоном и явно закрыть канал в atexit, после чего процесс корректно завершается.
Задача
Python controller scripts on Windows never exited, leaving zombie python.exe processes after simulation ended.
Результат
The patch eliminates the zombie process issue on Windows by making the helper thread daemon and ensuring the pipe is closed before the interpreter exits, allowing clean shutdown.
Рабочий процесс
- 1. Identify that python.exe stays alive after simulation ends.
- 2. Inspect Webots Python API (robot.py) to find StdStreamRedirect handling.
- 3. Discover helper thread is non‑daemon and blocks on readline waiting for EOF.
- 4. Realize EOF is sent only after atexit closes write end, causing deadlock.
- 5. Modify StdStreamRedirect: set daemon=True for helper thread.
- 6. In atexit callback, close write pipe, join thread, restore sys.stdout/sys.stderr.
- 7. Test on Windows 11 to confirm no hangs and exit code 0.
Доказательства
When running a controller with stdout/stderr redirection enabled (–stdout-redirect): ... python.exe never exited but stayed stuck in the background as a zombie process until forcefully killed.
The helper thread was created with daemon=False. It was blocked inside self._r.readline(), waiting for an EOF on the pipe.
The fix was clean and minimal: Daemonize the helper thread (daemon=True).
Tested on Windows 11 — zero hangs, instant exit with code 0.
- Дата записи: 2026-10-10T15:41:03.440Z