TerminateProcess via os.kill on Windows?

Hi Eryk, I’m not sure if there has been any changes to the implementation of os.kill in the last year, but I wanted to add to the discussion something I noticed when working with FastAPI and uvicorn.

Since Process.terminate() is using TerminateProcess(), using it for hot-reloading in uvicorn caused on_shutdown events to be skipped, so it was changed to os.kill(self.process.pid, signal.CTRL_C_EVENT) which correctly handles termination, but also kills any process that has been opened when using the multiprocessing module or Popen without the CREATE_NEW_PROCESS_GROUP flag. This kills an Python console app when using uvicorn with reload in a subprocess.

A discussion was opened about a half year ago at the uvicorn repo, but hasn’t gained much traction, I guess because there is really no solution that covers all cases, short of CPython doing something about it or going back to Popen.

Even if technically they are using os.kill wrong according to the docs because they’re not using the proper flag, I think it’s somewhat frustrating that the higher-level multiprocessing module does not offer a way to gracefully terminating a process in Windows, having to resort to os.kill which is incompatible with multiprocessing due to the impossibility of using creationflags.

Also the os.kill documentation is confusing as it suggests that you’re killing as specific process when in reality you’re calling GenerateConsoleCtrlEvent on the whole group. Moreover, it does not refer to the need of using subprocess.CREATE_NEW_PROCESS_GROUP, which might lead to incorrect use (such is the case with uvicorn)

I think the culprit is Win32 at the end of the day for not providing a API function to gracefully terminate a single process, but perhaps CPython could work around it by providing multiprocessing.Process with a new parameter like create_new_group, or maybe just take creationflags like Popen does.