4

I would like to have SIGCHLD functionality on Windows (i.e., notify the parent process when a child dies). I am aware that there is no equivalent to SIGCHLD in the Windows API, but I'd like to know what the common method is for implementing this with Windows. I'm sure that this is a problem that Windows developers encounter fairly often.

The only solution I can think of now involves polling the children to see if they are still alive.

Note: My application is single-threaded, and I would like to keep it that way if possible. The application has a non-blocking event loop (using select()).

Matt Fichman
  • 5,458
  • 4
  • 39
  • 59

2 Answers2

5

If you spawn these child process yourself you could use Job objects, they can notify you when a process that is part of your job has ended.

Use JobObjectAssociateCompletionPortInformation and catch JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS or JOB_OBJECT_MSG_EXIT_PROCESS.

Anders
  • 97,548
  • 12
  • 110
  • 164
  • Since *select* is not a good substitute for signals, and your method does not require me to spawn a thread for each process I think your method tis closest to what one may get for SIGCHLD in Windows, thanks – dashesy Feb 12 '13 at 16:49
5

I don't know if this is the best way, but it's certainly a way.

I assume you're creating the process with CreateProcess. This returns a PROCESS_INFORMATION structure that contains member hProcess. This is a handle to the child process you've created.

From here, you can wait on this handle with WaitOnSingleObject, which will block until the given handle is signalled (although it does take a timeout if you'd prefer to do this non-blocking - it's the closest equivalent to select you'll get).

If you do go the multi-thread route, then you can wait on a separate thread then when WaitOnSingleObject passes, you can notify a worker thread within the parent process accordingly.

In single-threaded style, you'll just be polling the handle in a loop if you use select-style semantics.

If you have several child objects to wait on (given you're already using select), you might want to consider WaitForMultipleObjects - if that's a pertinent model for your code.

Chris J
  • 30,688
  • 6
  • 69
  • 111
  • 1
    This route is less work than my answer and if fine if you only care about (and need to wait for) a single child but if you need information about grandchildren or if the child process does not wait for its children then you need a job object. – Anders Feb 10 '12 at 00:03
  • 2
    I concur: this is **the** way to wait for the completion of your children. Documented a million times in MSDN, too. Do not forget to ::CloseHandle() returned by ::CreateProcess(), whether or not you are waiting on it! Closing the handle does not affect the child process. – kkm inactive - support strike Feb 10 '12 at 13:02
  • Is there a way to use completion ports for this? I need to wait on potentially more than 64 children. – Matt Fichman Feb 13 '12 at 19:02