* PID's of processes and waiting. @ 2004-06-23 1:50 Eric 2004-06-23 3:18 ` Glynn Clements 2004-06-23 15:52 ` Michael Scondo 0 siblings, 2 replies; 4+ messages in thread From: Eric @ 2004-06-23 1:50 UTC (permalink / raw) To: linux-c-programming Hello, I am looking for a way to wait for a process to terminate. I have a process that was executed via system() and am getting its PID from a file it writes itself. I have a few questions. 1. Is it possible to directly get the PID of a processes executed via system()? I do not believe so that is why I am falling back to reading its file. 2. I have tried to waitpid() on the process by giving waitpid the PID read from the file as an argument, however it seems to return immidietly because I assume the new process is not a child of the calling process. Is it in fact a child of the calling process or am I abusing the systemcall? I assume a child is created only via fork()/exec() varients and this is the reason waitpid() is not working. 3. Is waiting to see when the /proc/PID directory disappears a reliable solution? Does this directory die on exit() and is handled by the kernel, or is this unreliable for one reason or another? I am aware that a race/deadlock may occur if a new process takes the PID of the old process I am waiting for in between the time I poll the directory, however, I am at a complete loss on how to wait on this process. I need a reliable indicator that the process has stopped wether gracefully or dying a horrible death. Currently I am polling its PID file...but that is VERY unreliable because it is not cleaned up on a SIGKILL. Does anyone have any ideas? Thanks in advance, Eric ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: PID's of processes and waiting. 2004-06-23 1:50 PID's of processes and waiting Eric @ 2004-06-23 3:18 ` Glynn Clements 2004-06-23 3:49 ` Eric 2004-06-23 15:52 ` Michael Scondo 1 sibling, 1 reply; 4+ messages in thread From: Glynn Clements @ 2004-06-23 3:18 UTC (permalink / raw) To: eric; +Cc: linux-c-programming Eric wrote: > I am looking for a way to wait for a process to terminate. I have a process > that was executed via system() and am getting its PID from a file it writes > itself. I have a few questions. > > 1. Is it possible to directly get the PID of a processes executed via > system()? I do not believe so that is why I am falling back to reading its > file. No. > 2. I have tried to waitpid() on the process by giving waitpid the PID read > from the file as an argument, however it seems to return immidietly because I > assume the new process is not a child of the calling process. Is it in fact a > child of the calling process or am I abusing the systemcall? I assume a child > is created only via fork()/exec() varients and this is the reason waitpid() > is not working. system("<command>") creates a child process with fork(), then the child process exec()s "/bin/sh -c <command>". Whether or not the process which is actually running the command is a child of the process which calls system() depends upon the exact command, and possibly upon the implementation of /bin/sh. Brief experimentation (where /bin/sh is bash-1.x) indicates that, for a simple command, it is a child process. OTOH, if the command is run in the background (e.g. system("foo &")), it won't be a child process (the child process fork()s and exit()s, with the grandchild process running the program). Similarly, for a sequence of commands (separated by ";"), or a pipeline, the child will be the shell with the actual commands being run in grandchild processes. Essentially, in order for the command to be run as a (direct) child of the process which called system(), the shell has to be able to exec() the command (as with the shell's "exec" built-in). This can only be done for a simple command; no sequences, pipelines, subshells, background commands etc. > 3. Is waiting to see when the /proc/PID directory disappears a reliable > solution? Does this directory die on exit() and is handled by the kernel, or > is this unreliable for one reason or another? At a theoretical level: 1. /proc may not be mounted (although, as an ever-increasing amount of software won't work without it, this is probably a remote possibility nowadays). 2. The process could die and the PID could be re-used between checks. On a more practical level, polling is best avoided where possible, as it consumes CPU time. If you poll frequently, it may use a lot of CPU time; if you poll less frequently, you introduce delays. > I am aware that a race/deadlock may occur if a new process takes the PID of > the old process I am waiting for in between the time I poll the directory, > however, I am at a complete loss on how to wait on this process. I need a > reliable indicator that the process has stopped wether gracefully or dying a > horrible death. Currently I am polling its PID file...but that is VERY > unreliable because it is not cleaned up on a SIGKILL. > > Does anyone have any ideas? In general, don't use system(). It's convenient for quick hacks, but like most things which are convenient for quick hacks (e.g. scripting languages), it makes it easy to write code which sorta-kinda-works, but is useless for writing code which works the way it ought to. Any non-trivial program which needs to spawn subprocesses should do the fork+exec+<whatever else> itself. OTOH, if it's inevitable that the process in question won't actually be a child of the process which initiates it (e.g. because the subprocess will be a daemon which needs to perform a second fork to detach itself from the session), it would probably be better to implement an explicit signalling mechanism, e.g. a pipe, socket, lock etc. The simplest mechanisms involve having the child hold a resource which will be released automatically (by the kernel) upon termination, and whose release the parent can detect. Using a pipe wouldn't require any dedicated code in the child. If the parent creates a pipe with the child inheriting the write end and the parent performing a blocking read on the other end, the parent will get EOF when there are no longer any writers, i.e. when the child (and any descendents) have died. An exclusive file lock is another option. If the child obtains a lock, and the parent makes a blocking attempt to obtain a conflicting lock, the parent will block until the child releases it (which will happen automatically if it dies). This has the advantage that it doesn't matter if the child spawns children of its own, as locks aren't inherited across a fork(), -- Glynn Clements <glynn.clements@virgin.net> ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: PID's of processes and waiting. 2004-06-23 3:18 ` Glynn Clements @ 2004-06-23 3:49 ` Eric 0 siblings, 0 replies; 4+ messages in thread From: Eric @ 2004-06-23 3:49 UTC (permalink / raw) To: Glynn Clements; +Cc: linux-c-programming On Tuesday 22 June 2004 10:18 pm, Glynn Clements wrote: > Eric wrote: > > I am looking for a way to wait for a process to terminate. I have a > > process that was executed via system() and am getting its PID from a file > > it writes itself. I have a few questions. > > > > 1. Is it possible to directly get the PID of a processes executed via > > system()? I do not believe so that is why I am falling back to reading > > its file. > > No. > > > 2. I have tried to waitpid() on the process by giving waitpid the PID > > read from the file as an argument, however it seems to return immidietly > > because I assume the new process is not a child of the calling process. > > Is it in fact a child of the calling process or am I abusing the > > systemcall? I assume a child is created only via fork()/exec() varients > > and this is the reason waitpid() is not working. > > system("<command>") creates a child process with fork(), then the > child process exec()s "/bin/sh -c <command>". > > Whether or not the process which is actually running the command is a > child of the process which calls system() depends upon the exact > command, and possibly upon the implementation of /bin/sh. > > Brief experimentation (where /bin/sh is bash-1.x) indicates that, for > a simple command, it is a child process. Yes I knew that. > OTOH, if the command is run in the background (e.g. system("foo &")), > it won't be a child process (the child process fork()s and exit()s, > with the grandchild process running the program). Similarly, for a > sequence of commands (separated by ";"), or a pipeline, the child will > be the shell with the actual commands being run in grandchild > processes. Ahh....so this is what I wanted to know. My process would be a grandparent so has little/no control. I kinda thought this, but wasn't 100% sure. > Essentially, in order for the command to be run as a (direct) child of > the process which called system(), the shell has to be able to exec() > the command (as with the shell's "exec" built-in). This can only be > done for a simple command; no sequences, pipelines, subshells, > background commands etc. > > > 3. Is waiting to see when the /proc/PID directory disappears a reliable > > solution? Does this directory die on exit() and is handled by the kernel, > > or is this unreliable for one reason or another? > > At a theoretical level: > > 1. /proc may not be mounted (although, as an ever-increasing amount of > software won't work without it, this is probably a remote possibility > nowadays). True. Reason #1 I knew it was shaky. > 2. The process could die and the PID could be re-used between checks. Very true. I wanted to avoid this at all costs. > On a more practical level, polling is best avoided where possible, as > it consumes CPU time. If you poll frequently, it may use a lot of CPU > time; if you poll less frequently, you introduce delays. Thats an excellent tip and will surely enhance my programming-to-come. Thank you. I was starting to see the delay/cost tradeoff as I spun on checking termination by open()/close() the PID file and checking open()'s exit status. > > I am aware that a race/deadlock may occur if a new process takes the PID > > of the old process I am waiting for in between the time I poll the > > directory, however, I am at a complete loss on how to wait on this > > process. I need a reliable indicator that the process has stopped wether > > gracefully or dying a horrible death. Currently I am polling its PID > > file...but that is VERY unreliable because it is not cleaned up on a > > SIGKILL. > > > > Does anyone have any ideas? > > In general, don't use system(). It's convenient for quick hacks, but > like most things which are convenient for quick hacks (e.g. scripting > languages), it makes it easy to write code which sorta-kinda-works, > but is useless for writing code which works the way it ought to. > > Any non-trivial program which needs to spawn subprocesses should do > the fork+exec+<whatever else> itself. My program has definatly grown beyond non-trivial. > OTOH, if it's inevitable that the process in question won't actually > be a child of the process which initiates it (e.g. because the > subprocess will be a daemon which needs to perform a second fork to > detach itself from the session), it would probably be better to > implement an explicit signalling mechanism, e.g. a pipe, socket, lock > etc. > The simplest mechanisms involve having the child hold a resource which > will be released automatically (by the kernel) upon termination, and > whose release the parent can detect. > > Using a pipe wouldn't require any dedicated code in the child. If the > parent creates a pipe with the child inheriting the write end and the > parent performing a blocking read on the other end, the parent will > get EOF when there are no longer any writers, i.e. when the child (and > any descendents) have died. > > An exclusive file lock is another option. If the child obtains a lock, > and the parent makes a blocking attempt to obtain a conflicting lock, > the parent will block until the child releases it (which will happen > automatically if it dies). This has the advantage that it doesn't > matter if the child spawns children of its own, as locks aren't > inherited across a fork(), Thank you. You gave an excellent response and convinced me that I need a more explicit way of controlling my subprocesses activity. I could see this to a point, but without more experience, I wasn't sure of all the different approaches I could take. ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: PID's of processes and waiting. 2004-06-23 1:50 PID's of processes and waiting Eric 2004-06-23 3:18 ` Glynn Clements @ 2004-06-23 15:52 ` Michael Scondo 1 sibling, 0 replies; 4+ messages in thread From: Michael Scondo @ 2004-06-23 15:52 UTC (permalink / raw) To: linux-c-programming > I am looking for a way to wait for a process to terminate. I have a > process that was executed via system() and am getting its PID from a file > it writes itself. I have a few questions. > here is how I have implemented somthing similar: int pid = fork(); if ( pid == 0 ) { exec( the child ); } int status; wait( pid, &status, 0 ); Have a look at man wait, the code above is pseudo code. ( There may be errors ) Kind regards Micha ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2004-06-23 15:52 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2004-06-23 1:50 PID's of processes and waiting Eric 2004-06-23 3:18 ` Glynn Clements 2004-06-23 3:49 ` Eric 2004-06-23 15:52 ` Michael Scondo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).