[Interest] QProcess: child read from stdin - no data received?

Till Oliver Knoll till.oliver.knoll at gmail.com
Mon May 14 13:40:04 CEST 2012


[*sigh* very sorry about that - here again to the proper recipient!]

2012/5/14 André Somers <andre at familiesomers.nl>:
>>> ...

>>> How does one get notified in a *child* process (started via QProcess) once there is data to be read on stdin (in a platform-independent matter - but for now mostly OS X)?
>> I came to realise that stdin/out are really *text*-based and trying to re-open them in binary mode is also not guaranteed to work everywhere:


>> ...
> How about using QSharedMemory for the actual JPEG data, and use either
> the QLocalServer/Socket or a StdIn/StdOut approach for the notifications
> that there is something to read? Seems more efficient than (de-)
> serializing images all the time.

I assume you mean the de-/serialisation effort required when trying to
send binary data over a "text-based connection" such as stdin/stdout:
I would have to use e.g. Base64 encoding.

However I expect the de-/serialisation effort when sending raw char *
data (or even a QByteArray) over a local socket (in the
QLocalSocket/-Server case) almost zero: send the number of bytes to
expect, followed by the raw data.

Off course the memory consumption with the QSharedSocket approach
would be twice as large as with the shared memory approach, I agree:
the JPEG data would reside in the parent process address space and a
*copy* thereof would end up in the child process address space.
However I just realised that this is also the case with shared memory
where I would also have to make a *copy* of the original JPEG data
into the shared memory segment - so no gain here (leaving temporary
system buffers for the local socket approach away for the sake of
simplicity of my argument ;))

But going back to the stdin-/out case: I thought about this "mixed
IPC" approach as well: send the text-based messages such as "JPEG Data
now coming" via stdin to the child process, which then starts reading
the actual data from the shared memory.

However, to my understanding you have to define initially the size of
the shared memory in

  http://qt-project.org/doc/qt-4.8/qsharedmemory.html#create

So either I have to allocate a memory segment "large enough to hold
the possibly largest JPEG data I am expecting" (e.g. "HDTV resolution
* 4 Bytes + some extra bytes for JPEG meta data, to be on the very
save side), which would be very wasteful (the aforementioned formula
assumes uncompressed data with an alpha component, which would most
likely never be needed, even with a JPEG quality factor of 100%
(almost no compression)).

Or I would have to implement what I called previously a "memory-based
block read/write protocol" by e.g. just allocating N KBytes of shared
memory, and send request and acknowledgement messages back and forth,
until the entire JPEG data was transerred over this "shared buffer".

Or I would re-create and drop the shared memory segment each time with
the proper size, but not sure how efficient that would be...


> You could even use something like
> QxtRPCPeer[1] for the communication between the two programs.


>From what I quickly read the main feature of this library seems to be
to carry Qt signals across (network) boundaries. So unless there was a
way to limit the networking part to "local sockets" only that would
not work in my scenario, because "when acting as a server, it uses a
QxtTcpConnectionManager to accept connections", and TCP connections is
*exactly* what I am trying to avoid in the parent process ;) (1)

So while the possibility to use Qt signals across process boundaries
certainly is appealing in my case I really just need a very simple
"messaging" protocol, basically enum values which indicate what to do,
followed by the actual JPEG data or a few other meta informations as
"arguments" (+ the number and size of the actual data as "protocol
overhead").

So QLocalSocket and -Server seems to be a good match, except for this
Warning message I currently get when the application is actually
sandboxed (see other post of mine "OS X Sandboxing and IPC").


Thanks,
  Oliver

(1) I think the underlying framework Apple is using to implement the
"process privileges" can distinguish between "Internet connections"
and "Local connections" - however in the available Entitlements list I
just see com.apple.security.network.client ("Outgoing network socket
for connecting to other machines") and
com.apple.security.network.server ("Incoming network socket for
listening for requests from other machines") which don't seem to
differentiate between "local" and "remote" connections. But maybe that
means that when e.g. listening on some TCP socket, but only accepting
local addresses (i.e. from 127.0.0.1) no special entitlement at all is
necessary - haven't tried it.
 http://developer.apple.com/library/ios/#DOCUMENTATION/Miscellaneous/Reference/EntitlementKeyReference/EnablingAppSandbox/EnablingAppSandbox.html



More information about the Interest mailing list