|
|
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
> ... 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
|
|
| |
| |
|
|
|
|
| |
|
|