vibe.d - asynchronously wait() for process to exit

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Jun 21 05:06:59 PDT 2016


On 6/20/16 11:01 PM, Vladimir Panteleev wrote:
> On Monday, 20 June 2016 at 19:39:42 UTC, Steven Schveighoffer wrote:
>> On 6/20/16 12:29 PM, Vladimir Panteleev wrote:
>>> On Monday, 20 June 2016 at 16:16:32 UTC, Steven Schveighoffer wrote:
>>>> What is the OS support for waitid
>>>> (http://man7.org/linux/man-pages/man2/waitpid.2.html)? Seems to have
>>>> support for async waiting of multiple processes (at least it can
>>>> return immediately if no child has exited). One consideration is how
>>>> responsive you need to be to a process exiting -- is it ok for example
>>>> to be notified 500ms after the process exits? If so, you can
>>>> interleave timed waits for socket data with a check to see if any
>>>> process exits. I've done this in the past for such things. I don't
>>>> know how well this works for libevent though.
>>>
>>> std.process has tryWait() if polling were acceptable, but I would really
>>> like to avoid it. Or have I misunderstood?
>>
>> tryWait works on a single PID. From my reading of the docs, it appears
>> you can call waitid and no matter how many children you have, if one
>> exits, then it will capture that.
>
> Ah, OK. But then so does SIGCHLD, asynchronously.

But not where you need it to be handled :) This is the reason for the 
"self pipe trick" that you use.

I'll note that waitid actually isn't needed, you can do waitpid(-1, ...) 
and it waits for any process. I didn't realize that before.

>> It would be nice if the Linux wait mechanisms were all standardized
>> similar to Windows. I think the only thing that allows such universal
>> access is file descriptors. Processes are definitely a case where it's
>> not easy to deal with the events. Signal handlers suck as an async
>> mechanism.
>
> It's really not that hard. It's just that no one bothered to implement
> this correctly in Vibe. Process or signal handling does not seem to be a
> Vibe.d driver primitive.
>
> Signals interrupt blocking calls such as select/poll. Even if you don't
> have a signal handler registered, you could in theory call tryWait or
> similar on every process ID you're waiting on in an event loop idle
> handler. It's not very efficient, of course, and degrades poorly as the
> number of processes and events grows.

Only if you handle the signal in that thread.

>
> You can also register a signal handler, and just ping a socket pair
> (unmanaged on one side, managed by the event loop on the other). This is
> what I do in ae.

Yeah, probably the right thing to do is a signal handler that reaps all 
terminated processes, putting the data into the pipe/socket.

> As I recently learned, there's also signalfd. With that, had Vibe.d had
> a primitive to wrap a file descriptor into a stream it can manage, it
> would be as simple as reading from it. But it doesn't seem to have one
> so I guess you need to use createFileDescriptorEvent and the raw C
> read() function.

Hm... I hadn't heard of this. Some seem to think that creates its own 
problems, but I don't know if SIGCHLD is one of them since that's 
blocked by default: https://ldpreload.com/blog/signalfd-is-useless

>> But my point was that you can poll on every start of event loop, and
>> handle process exits if they are ready, and then every 500ms or so if
>> no i/o becomes ready. In practice, this should be pretty responsive,
>> unless you are only doing process execution and no i/o. And half
>> second delay between process exit and handling of result is pretty
>> small even in that case.
>
> Sure, but to be honest that's nothing but an ugly hack. :) Even if not
> for the 500ms delay - every bit adds up, and timers are much worse than
> event handling on e.g. mobile devices than servers, because they incur a
> CPU wake-up and then end up doing nothing most of the time.

What are you doing spawning child processes on a mobile device? :)

-Steve


More information about the Digitalmars-d-learn mailing list