Communicating with external processes in D
Adam D. Ruppe via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Mon Nov 23 12:21:12 PST 2015
On Monday, 23 November 2015 at 20:02:16 UTC, Cameron Reid wrote:
> Is such a thing possible? If so, where might I go to educate
> myself?
Yes, though the D stdlib doesn't help a whole lot, unless you
want to use threads and that's blargh, I hate using threads and
recommend you avoid them when you can. If you do want to try them
you can just spawn a new thread for each child then block until
it talks to you.
But without threads, well, Phobos helps a little, but you'll want
to get platform-specific to go the rest of the way (and at that
point, you might as well just use the OS functions all the way
down but whatever).
Creating the process is simple enough: you can DIY with
pipe/fork/exec/dup2 (on Posix), CreatePipe/CreateProcess (on
Windows), or go ahead and let Phobos help you with pipeProcess.
Whatever you're more comfortable with at that point. Now the
program is running and you have a handle to the pipes to talk to
it.
Next, you want to be alerted when one of them is ready. This is
where Phobos won't help much (though a lib like vibe.d might, I
don't know though) and you want to use an operating system
function.
On Posix, one of the select/poll family of functions will do what
you want. If you have just a handful of processes, select is easy
enough to use and will do the job. On Windows, you'll want
WaitForMultipleObjects which works similarly (or you could use
overlapped I/O on the pipe which is actually pretty elegant but
pretty different to use too).
These functions take an array of file numbers/file handles and
tells you when one of them is ready to read. If you pass all your
read pipes from the children to them, you'll be alerted when any
of them writes back to you. You will handle them serially when a
message comes in (so you prolly want to handle it quickly if you
can), but all the children run in parallel.
I find this generally easier to code than the threaded solution
and it is also generally more efficient while keeping a lot of
the same benefits.
Anyway, if you used Phobos' pipeProcess to create the pipes, you
get the platform-specific handles through these functions:
http://dlang.org/phobos/std_stdio.html#.File.fileno file.fileno
and File.windowsHandle for Windows (use `version(Windows) { win
version } else version(Posix) { posix version } else static
assert(0, "unsupported OS");`).
Once you have the handles, you call the OS functions just like
you would in C. If you need an example, I can write one up, but I
suggest just looking up a C example and remembering:
import core.sys.posix.sys.select; // same as
#include<sys/select.h> in a C example
import core.sys.windows.windows; // has WaitForMultipleObjects
from C in there
will get you started. So import them, add the files to your list,
then call the function so the OS waits and tells you when any of
them are ready, then loop over it and handle the input again.
More information about the Digitalmars-d-learn
mailing list