Hi Larry,
OK, I was toying with the idea of using a pipe to pass data from one
program to another. The idea was that PGM1 would write to the pipe
and PGM2 would read from it - both in the same job. The idea was that
in this particular case we could use a pipe in place of a pointer -
no need to allocate/reallocate/deallocate or keep track of size. I
got an example working nicely, as we already have code using pipes
for inter-process communications. However, there would seem to be a
32k limit on the pipe which puts a severe restriction on it.
Pipes are intended for real-time communication. In other words, when
you write data to a pipe, it's expected that another job (or thread)
will be reading from it (concurrently.)
They are NOT intended as a place to store data temporarily. If you want
something like that, use a data queue instead. It's intended only for
writing data while another program is reading it.
Most programs use a model of "read something, process it, read more,
process more, etc". Because of this model, there's a good chance that
when one program writes data to a pipe, the other program will (for an
instant or two) be doing processing. Therefore, pipes are buffered, so
that data can be kept in memory long enough for the other job to finish
it's processing and read the data from the pipe. It sounds like this
buffer is around 32k long -- but I wouldn't rely on that always being
the case.
So pipes aren't a good mechanism for communicating between two programs
in the same job, because (unless it's multi-threaded) the two programs
aren't running concurrently. By contrast, if they're running in
separate jobs, they are concurrent, and pipes work very well.
STDIN and STDOUT work similarly to pipes, except, by default they read
input from the keyboard and write output to the display. They can be
redirected to pipe (via QShell or a similar tool) but in that case, you
are actually using pipes, and the same restrictions apply as would with
pipes.
Furthermore, by default, descriptors 0, 1 and 2 are NOT mapped on the i.
That's a Unix-like mechanism. There's an environmnet variable
QIBM_USE_DESCRIPTOR_STDIO that can be used to change that so that these
descriptors ARE mapped to 0,1,2. Otherwise, if you run your program
from QShell, or from an HTTP server like Apache, the descriptors should
be automatically mapped.
The EPIPE error (broken pipe, CPE3455) would happen if you tried to
write to a descriptor without it being mapped.
If I want to use this type of programming model, I typically use the
pipe() API to create my pipes, then use the spawn() API to map
stdout/stderr/stdin to the pipes I created. spawn() will run your
program in a child job, so it'll be able to run concurrently. (I'm
pretty sure that spawn() is what QShell uses under the covers, as well.)
the spawn() API also gives you the opportunity to set environment
variables in the spawned job, so you can set QIBM_USE_DESCRIPTOR_STDIO
while you're at it.
But, if you want to keep your programs in the same job, I'd consider
using a data queue, file, user space, or parameters to pass data between
them.
As an Amazon Associate we earn from qualifying purchases.