-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: os: Goroutine-friendly waiting on processes #60481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Maybe because it is named "Go" it naturally is adverse to "Wait"...? 🤡 |
The os package is intended to be somewhat OS independent. Some aspects of this only seem to make sense on Unix systems. It's not yet obvious to me why we need new API. Programs that need this level of control over subprocesses are likely system dependent and can use the syscall API. I don't see a reason to worry about conflicts between the syscall API and the os API; if you need the syscall API, use only the syscall API. Then you can take advantage of whatever facilities the operating system provides, and can produce the same channel-based API that you are describing here. |
But I am not free to use whatever I want, because if I want to use I really find here analogy with |
Alternative could be that |
That is exactly the crucial point IMHO that the OP brings forward with his proposal. Regarding the "wrapping" I see problems with the many command and process-related packages already out there for some time and it might often need package updates deep down the chain to enable this feature. That's why I find the OP's proposal highly useful from my developer's consumer point of view. |
Ping? |
@thediveo There are more than 200 open proposals, unfortunately. We will get to this one. Thanks. |
I'm dealing with the same issue in https://github.com/buildbarn/bb-remote-execution/. I currently need to wrap execution of all workers into |
A closely related issue is that there doesn't seem to be a way to incorporate a On Linux (including Android) this is possible with |
@ringerc As you point out, there is already a way to use |
Waiting on a sub-process in Go (or through
Process.Wait
orsyscall.Wait4
) does not align well with multi-threaded goroutine-based Go programs. At least on Linux they call intowaitpid
syscall (or one of related ones likewaitid
) which are designed that a process can call wait on a subprocess only once. While writing my init project in Go I realized this is a limitation which makes it hard to make whole program modular. You cannot have multiple different parts of a program observe status of subprocesses, e.g., one for logging what is happening with all subprocesses, another for spawning and waiting for programs, third for reaping unknown zombies who got reparented to the init process, and lastly if your init uses ptrace to inspect those unknown processes, you even hit bugs #60321 and in combination with reaping loop you have a problem that it might be the reaping loop which gets its wait woke up after you attach to the subprocess.In short, currently having in a Go program just one
process.Wait()
and anothersyscall.Wait4(-1, ...)
create an inherently racy execution which makes it hard to have a modular program. E.g., installing go-reaper package inherently breaks anyprocess.Wait
, sometimes, randomly, in hard to debug manner.Because of this I propose that a new API is introduced which hides away the complexities of waiting on sub-processes in a similar way how
os.signal
package does for signal handling. Signal handling also has similar limitations at a low level, but because there is a Go abstraction which maps them into channels, any part of a program can hook into signals without interfering with the rest of the program. I propose the following API:WaitPidfd is Linux specific. Maybe it could be extended to Windows process handles as well?
Current possible list of states/codes are inspired by unix. Not all of them will be relevant on other platforms. Maybe there are other states we should add other platforms have, but I am not familiar with them? I think possible states should be an union of what is available on supported platforms because the API is cross-platform.
I use context instead of explicit
Stop
like signal package has as I find it more modern and suitable for a new API. We could provide both or justStop
if others feel differently.WaitInfo
is inspired byWaitStatus
and API is similar on purpose.This has to be in the core Go library as
os.exec
andos.Process
should use this internally (any anything else waiting on processes in stdlib), otherwise we didn't fix the main issue.The text was updated successfully, but these errors were encountered: