I've got a c++ application with certain items in a queue, those items then are going to be processed by a python script. I want it so that at maximum 10 instances of the python script are running. I plan on using execl() to launch the python process, Is there a way to tell that the process has quit without having to pass a message back to the parent process?
execl doesn't launch a process -- it overlays the existing process with another executable. fork does launch a process -- and returns the child process's id (aka pid) to the parent process (returns 0 to the child process, that's how the child knows it's the child so it can clean things up and exec). Use the children's pids to check if they're finished or not, or trap SIGCHLD to keep track of that.
I recommend the SIGCHLD so you don't have to "poll" to see if some process has terminated, but the latter approach isn't too hard either -- just execute once in a while:
def whosdone(pids):
nope = []
done = []
for pid in pids:
try: os.kill(pid, 0)
except OSError: nope.append(pid)
else: done.append(pid)
return done, nope
i.e. you can periodically call done, pidslist = whosdone(pidslist) and do whatever you need to do about the PIDs that are done. Of course, when you fork, use the idiom:
pid = os.fork()
if pid: # we're the parent process
pidslist.append(pid)
else: # we're the child process
# clean things up, etc, then exec
If you are doing this in C++ under unix/linux, check out wait(), waitpid(), waitid(), wait3(), or wait4(). You can invoke waitpid() NOHANG (polling) or have it block until a child process completes. Pid (process-id) is the value returned by fork().
I did a painful "hard way" example of fork() earlier (using dup2() to re-route IO).