tags:

views:

258

answers:

2

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?

+4  A: 

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
Alex Martelli
Would you be able to expand on how to check the children's pid's to check if their finished? I don't understand how that would tell me if their finished or not
whatWhat
os.kill(pid, 0) raises an OSError exception if process pid has terminated (or is owned by another user), no exception if pid is running for the current user -- no other effect. There, let me edit my answer...
Alex Martelli
Wouldn't it be better to use os.wait(0, os.WNOHANG)? This will reap the child process, removing a resource leak, and avoid having to iterate over every child.
bdonlan
@bdonlan, I think you mean os.waitpid(-1, os.WNOHANG) [-1 to ignore process-group issues], and that would be fine too, if the process doesn't spawn other children it doesn't care about. But SIGCHLD is still better (I gave the wikipedia URL for it above) and can be paired with .wait or .waitpit.
Alex Martelli
A: 

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).

Mr.Ree