POV-Ray : Newsgroups : povray.off-topic : Linux: best way to communicate between processes? Server Time
23 Dec 2024 11:22:46 EST (-0500)
  Linux: best way to communicate between processes? (Message 1 to 10 of 22)  
Goto Latest 10 Messages Next 10 Messages >>>
From: scott
Subject: Linux: best way to communicate between processes?
Date: 16 May 2016 08:47:30
Message: <5739c162@news.povray.org>
On my pi I'm running raspbian, and have a process running as root to 
read a pin on the GPIO (connected to a PIR). Only root can read the GPIO 
pins, but obviously I don't want large, complex programs running as root 
just because they need to read a pin on the GPIO.

What's the best way for this root process to "broadcast" to other 
(non-root) processes when that pin goes high? It will only happen at 
maximum frequency of about every 2 seconds, but any delay between the 
pin going high and the other processes seeing it should be minimal.

I did think about using a file, that was write permission only for root, 
but readable by everyone, that seems like a lot of overhead though (and 
what if root tries to write to it as someone else is reading it?). In 
Windows I might consider using a broadcast message with the PostMessage 
API function, is there something similar for Linux?


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: Linux: best way to communicate between processes?
Date: 16 May 2016 13:21:36
Message: <573a01a0$1@news.povray.org>
On 16/05/2016 01:47 PM, scott wrote:
> What's the best way for this root process to "broadcast" to other
> (non-root) processes when that pin goes high? It will only happen at
> maximum frequency of about every 2 seconds, but any delay between the
> pin going high and the other processes seeing it should be minimal.

So you're mostly worried about latency. (?)

> I did think about using a file, that was write permission only for root,
> but readable by everyone, that seems like a lot of overhead though (and
> what if root tries to write to it as someone else is reading it?). In
> Windows I might consider using a broadcast message with the PostMessage
> API function, is there something similar for Linux?

Writing to a file (or, more likely, a *named pipe*) seems like a 
reasonable way to do this, especially considering the low frequency of 
updates. Hell, at this speed, you could almost create / delete an entire 
empty file as your flag signal!

You could instead try TCP (or UDP), but I'd expect that to have much 
higher overhead. I don't know if Unix sockets are any quicker.

Alternatively, learn how dbus works? Or MPI. Or one of the other 
existing messaging frameworks.

Personally, if it were me, I'd go with named pipe. But I guess that's 
just because I've used it before and I know how it works...


Post a reply to this message

From: Le Forgeron
Subject: Re: Linux: best way to communicate between processes?
Date: 16 May 2016 13:26:45
Message: <573a02d5$1@news.povray.org>
Le 16/05/2016 14:47, scott a écrit :
> On my pi I'm running raspbian, and have a process running as root to read a pin on
the GPIO (connected to a PIR). Only root can read the GPIO pins, but obviously I don't
want large, complex programs running as root just because they need to read a pin on
the GPIO.
> 
> What's the best way for this root process to "broadcast" to other (non-root)
processes when that pin goes high? It will only happen at maximum frequency of about
every 2 seconds, but any delay between the pin going high and the other processes
seeing it should be minimal.
> 
> I did think about using a file, that was write permission only for root, but
readable by everyone, that seems like a lot of overhead though (and what if root tries
to write to it as someone else is reading it?). In Windows I might consider using a
broadcast message with
> the PostMessage API function, is there something similar for Linux?

A low latency signaling system... with low volume of data.

one of the fastest might be using kill (2), but the root process need to get a
list of registered process to signal, and each registered process must have
registered a handling routine for the signal.
Number of available signal is low, so not a scalable solution for too much items.
There is a few restriction on the handling routine too. And signals do not stack
(signaling twice the same signal before it got handled is not to be seen)

To perform the registration... might depend on the number of processes which must
be signaled. (and do not forget to have mechanism to cancel the registration
when one process exits, even with a crash)

If processes can or need to perform active monitoring, a shared memory segment
can be used. You just need to be able to select a common key.
For a fixed-number of processes architecture, the registration process might be
a shared memory segment, but you would need a kind of keep-alive sub-part in it.

A substitute to a real file would be a named pipe (with a bit of locking, it can even
provides information about the other end being dead), served by the root process.

The interest of "file" like solution is using select() to dispatch event.

If you are in a graphical desktop, there might be some messaging/bus system too, but
latency is another story.


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: Linux: best way to communicate between processes?
Date: 16 May 2016 14:29:05
Message: <573a1171$1@news.povray.org>
On 16/05/2016 06:26 PM, Le_Forgeron wrote:
> A low latency signaling system... with low volume of data.
>
> one of the fastest might be using kill (2),

Damn, I hadn't even thought of that. Good call.

> but the root process need to get a
> list of registered process to signal, and each registered process must have
> registered a handling routine for the signal.

You could do something like have the listener send SIGUSR1 to the root 
process, which then remembers the PID of the process that signalled it, 
and signals it back until it dies.

(I'm not sure of the security implications of different processes 
signalling each other; I *believe* you just need to know the PID of the 
destination, but I may be wrong...)

> There is a few restriction on the handling routine too. And signals do not stack
> (signaling twice the same signal before it got handled is not to be seen)

Yeah, I'm told writing signal handles is fraught with "subtle" race 
conditions and such.

> If processes can or need to perform active monitoring, a shared memory segment
> can be used. You just need to be able to select a common key.

Another excellent solution I hadn't thought of. Though I'm unclear on 
how you do this in Linux; do you just mmap the same backing file from 
two different processes? Regardless, that should avoid the need to 
switch to kernel mode to send messages - although it does seem to 
require the receiver to poll for them...

> A substitute to a real file would be a named pipe (with a bit of locking, it can
even
> provides information about the other end being dead), served by the root process.
>
> The interest of "file" like solution is using select() to dispatch event.

Indeed.

> If you are in a graphical desktop, there might be some messaging/bus system too, but
latency is another story.

In my day job, I wrote some stuff that's powered by AT-SPI, which uses 
dbus under the hood. I don't know much about it, though. (I gather it 
uses Unix sockets to do its actual work... And a central daemon to 
gather and route messages...)


Post a reply to this message

From: Jim Henderson
Subject: Re: Linux: best way to communicate between processes?
Date: 17 May 2016 01:33:41
Message: <573aad35$1@news.povray.org>
On Mon, 16 May 2016 13:47:30 +0100, scott wrote:

> On my pi I'm running raspbian, and have a process running as root to
> read a pin on the GPIO (connected to a PIR). Only root can read the GPIO
> pins, but obviously I don't want large, complex programs running as root
> just because they need to read a pin on the GPIO.
> 
> What's the best way for this root process to "broadcast" to other
> (non-root) processes when that pin goes high? It will only happen at
> maximum frequency of about every 2 seconds, but any delay between the
> pin going high and the other processes seeing it should be minimal.
> 
> I did think about using a file, that was write permission only for root,
> but readable by everyone, that seems like a lot of overhead though (and
> what if root tries to write to it as someone else is reading it?). In
> Windows I might consider using a broadcast message with the PostMessage
> API function, is there something similar for Linux?

Sockets are fairly common, or you might look to see if the Raspbian 
kernel has "capabilities" functionality that would let you grant a non-
root user access to the GPIO pins.

Jim
-- 
"I learned long ago, never to wrestle with a pig. You get dirty, and 
besides, the pig likes it." - George Bernard Shaw


Post a reply to this message

From: scott
Subject: Re: Linux: best way to communicate between processes?
Date: 17 May 2016 03:18:48
Message: <573ac5d8$1@news.povray.org>
On 16/05/2016 18:21, Orchid Win7 v1 wrote:
> On 16/05/2016 01:47 PM, scott wrote:
>> What's the best way for this root process to "broadcast" to other
>> (non-root) processes when that pin goes high? It will only happen at
>> maximum frequency of about every 2 seconds, but any delay between the
>> pin going high and the other processes seeing it should be minimal.
>
> So you're mostly worried about latency. (?)

Yes, but we're talking a tenth of a second being fine here, microseconds 
are not needed!

>> I did think about using a file, that was write permission only for root,
>> but readable by everyone, that seems like a lot of overhead though (and
>> what if root tries to write to it as someone else is reading it?). In
>> Windows I might consider using a broadcast message with the PostMessage
>> API function, is there something similar for Linux?
>
> Writing to a file (or, more likely, a *named pipe*) seems like a
> reasonable way to do this, especially considering the low frequency of
> updates. Hell, at this speed, you could almost create / delete an entire
> empty file as your flag signal!
>
> You could instead try TCP (or UDP), but I'd expect that to have much
> higher overhead. I don't know if Unix sockets are any quicker.
>
> Alternatively, learn how dbus works? Or MPI. Or one of the other
> existing messaging frameworks.
>
> Personally, if it were me, I'd go with named pipe. But I guess that's
> just because I've used it before and I know how it works...

Thanks for the ideas everyone.

Just looked up named pipes - it seems you can only have a single 
"reader"? I need more than one process to be able to see the signal.

Sockets should work ok, or as you state, just create/delete an empty 
file somewhere. I'll have to experiment. I guess at some point I might 
want to expand the signal to more than one pin, so being able to 
communicate an "int" rather than a "bool" would actually be more scalable.


Post a reply to this message

From: dick balaska
Subject: Re: Linux: best way to communicate between processes?
Date: 17 May 2016 05:41:20
Message: <573ae740$1@news.povray.org>
Am 2016-05-17 01:33, also sprach Jim Henderson:
>
> Sockets are fairly common, or you might look to see if the Raspbian
> kernel has "capabilities" functionality that would let you grant a non-
> root user access to the GPIO pins.

I would use a socket.


-- 
dik


Post a reply to this message

From: jr
Subject: Re: Linux: best way to communicate between processes?
Date: 17 May 2016 06:04:49
Message: <573aecc1$1@news.povray.org>
hi,

On 17/05/2016 08:18, scott wrote:
> On 16/05/2016 18:21, Orchid Win7 v1 wrote:
>> On 16/05/2016 01:47 PM, scott wrote:
>>> What's the best way for this root process to "broadcast" to other
>>> (non-root) processes when that pin goes high? It will only happen at
>>> maximum frequency of about every 2 seconds, but any delay between the
>>> pin going high and the other processes seeing it should be minimal.
>>
> file somewhere. I'll have to experiment. I guess at some point I might
> want to expand the signal to more than one pin, so being able to
> communicate an "int" rather than a "bool" would actually be more scalable.

conceptually, the "device" ought to provide an entry under /proc
somewhere, and clients would read /proc/what/ever to retrieve the (int)
value.

jr.


Post a reply to this message

From: scott
Subject: Re: Linux: best way to communicate between processes?
Date: 17 May 2016 06:44:02
Message: <573af5f2$1@news.povray.org>
> ... or you might look to see if the Raspbian
> kernel has "capabilities" functionality that would let you grant a non-
> root user access to the GPIO pins.

I did look this up previously, and the solution seemed to be to change 
the permissions of the entire memory map, so that non-root users could 
access it. I don't like the sound of that either :)


Post a reply to this message

From: Le Forgeron
Subject: Re: Linux: best way to communicate between processes?
Date: 17 May 2016 08:30:09
Message: <573b0ed1$1@news.povray.org>
Le 17/05/2016 à 09:18, scott a écrit :
>
> Just looked up named pipes - it seems you can only have a single
> "reader"? I need more than one process to be able to see the signal.

named pipe are unidrectional, and a single reader is the thing.

The server (root process) should create a root_pipe to which it will 
read "long" data.

The other process should create their own my_name_pipe to which they 
would read short data.

How it could work:

One other process opens in write mode the root_pipe (it get a file 
descriptor), use a write-lock on that file descriptor, send the name 
(aka path) of its my_name_pipe (as encapsulated data, beware of variable 
length), relequish the write-lock on the file descriptor and might even 
close the file descriptor.

The root process, upon having something to read in the root_pipe, 
retrieve the name of the named pipe of the other process (this is where 
variable length can be painful), then opens the other's name pipe in 
write mode and stack the file descriptor in its internal structure.

Upon event to signal, the root process loops for each stacked file 
descriptor and sent a byte.



Added sugar, detection of dead processes by root process:
The other process should lock the file descriptor it use to read its 
named pipe, as soon as possible and forever. (lockf or flock, you need 
to dive into their man pages, one of them is the right one to use)

The root process, before writing a byte for the event, should try to 
lock the same named_pipe (via its file descriptor) and that try should 
fail. If it succeed, the reading end is dead, and there is no need to 
send a byte, just close the file descriptor and remove it from the 
internal structure.

Caveat: that solution does not work over an NFS partition.


Extra strawberry on top: the root process should put the outgoing named 
pipe in non-blocking mode, to avoid being frozen by a full pipe and a 
stalled reader.


Post a reply to this message

Goto Latest 10 Messages Next 10 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.