EmbeddedRelated.com
Forums

Embedded Linux: share data among different processes

Started by pozz June 23, 2016
I'm new to embedded Linux so this question could be very simple for many 
of you. Most probably, it isn't directly related to embedded world, but 
to Linux OS generally. Anyway I think it is a common scenario in 
embedded applications.

I'm going to develop a local/remote control of an electronic device. It 
communicates through a RS485 link.
The local control will be a touch-screen display (I'm going to use QT 
graphic libraries).
The remote control will be HTTP (web server).

I think a good approach will be to develop a simple application, the 
poller, that communicates with the electronic device and implements the 
RS485 protocol. The poller continuously acquires the current 
status/settings of the device and store them in some "shared" way.

The graphic application (QT-based) and the web server (CGI) should 
access to the data retrieved by the poller.

What is the best method to share the data generated by an application 
(the poller) among two or more applications (QT and CGI)?
In this scenario, I think it's important to lock the "shared data" 
before accessing them (reading or writing), in order to avoid reading 
incoerent data. Indeed, if the poller writes the data at the same time 
(Linux OS is multi-tasking) the web server reads them, they could be 
incoerent.

I'm thinking to use SQLite database to store the data. The poller writes 
the database, HTTP and QT reads from it. It seems SQLite will take care 
the multi-thread/multi-process scenario.

Any suggestions?
Il giorno giovedì 23 giugno 2016 13:52:19 UTC+2, pozz ha scritto:
> I'm new to embedded Linux so this question could be very simple for many > of you. Most probably, it isn't directly related to embedded world, but > to Linux OS generally. Anyway I think it is a common scenario in > embedded applications. > > I'm going to develop a local/remote control of an electronic device. It > communicates through a RS485 link. > The local control will be a touch-screen display (I'm going to use QT > graphic libraries). > The remote control will be HTTP (web server). > > I think a good approach will be to develop a simple application, the > poller, that communicates with the electronic device and implements the > RS485 protocol. The poller continuously acquires the current > status/settings of the device and store them in some "shared" way. > > The graphic application (QT-based) and the web server (CGI) should > access to the data retrieved by the poller. > > What is the best method to share the data generated by an application > (the poller) among two or more applications (QT and CGI)? > In this scenario, I think it's important to lock the "shared data" > before accessing them (reading or writing), in order to avoid reading > incoerent data. Indeed, if the poller writes the data at the same time > (Linux OS is multi-tasking) the web server reads them, they could be > incoerent. > > I'm thinking to use SQLite database to store the data. The poller writes > the database, HTTP and QT reads from it. It seems SQLite will take care > the multi-thread/multi-process scenario. > > Any suggestions?
do you need to keep the data from the RS485 or not? If not a shared memory or (named) pipe or something like this accessed through a semaphore or a mutex is IMHO better. Some reading: http://web.archive.org/web/20150524005553/http://advancedlinuxprogramming.com/alp-folder/alp-ch05-ipc.pdf http://web.archive.org/web/20150511104538/http://www.advancedlinuxprogramming.com/alp-folder/ On the other hand, if you need to keep the data then a DB is the way to go. Bye Jack
Jack wrote:

> Il giorno giovedì 23 giugno 2016 13:52:19 UTC+2, pozz ha scritto: >> I'm new to embedded Linux so this question could be very simple for many >> of you. Most probably, it isn't directly related to embedded world, but >> to Linux OS generally. Anyway I think it is a common scenario in >> embedded applications. >> >> I'm going to develop a local/remote control of an electronic device. It >> communicates through a RS485 link. >> The local control will be a touch-screen display (I'm going to use QT >> graphic libraries). >> The remote control will be HTTP (web server). >> >> I think a good approach will be to develop a simple application, the >> poller, that communicates with the electronic device and implements the >> RS485 protocol. The poller continuously acquires the current >> status/settings of the device and store them in some "shared" way. >> >> The graphic application (QT-based) and the web server (CGI) should >> access to the data retrieved by the poller. >> >> What is the best method to share the data generated by an application >> (the poller) among two or more applications (QT and CGI)? >> In this scenario, I think it's important to lock the "shared data" >> before accessing them (reading or writing), in order to avoid reading >> incoerent data. Indeed, if the poller writes the data at the same time >> (Linux OS is multi-tasking) the web server reads them, they could be >> incoerent. >> >> I'm thinking to use SQLite database to store the data. The poller writes >> the database, HTTP and QT reads from it. It seems SQLite will take care >> the multi-thread/multi-process scenario. >> >> Any suggestions? > > do you need to keep the data from the RS485 or not? > > If not a shared memory or (named) pipe or something like this accessed > through a semaphore or a mutex is IMHO better. Some reading: >
http://web.archive.org/web/20150524005553/http://advancedlinuxprogramming.com/alp- folder/alp-ch05-ipc.pdf
>
http://web.archive.org/web/20150511104538/http://www.advancedlinuxprogramming.com/alp- folder/
> > On the other hand, if you need to keep the data then a DB is the way to > go. > > Bye Jack
Since you already using Qt, I can propose a solution which I use quite often. It is even flying in more than 100 helicopters. Yes, penguins can fly :-) The poller fetches that data from the remote device via RS485 and keeps a for it local copy. If permanent storage is a requirement it can also take care of this. In addition it open a QLocalServer which listens for connections from other processes. The other (multiple) processes connect to this server using a QLocalSocket. They can then poll are are sent the data directly when the poller receives new data. This way no locking is required since the poller does its sending in a single thread. You just have to define a simple protocol. It could be line oriented ASCII. You can also use QTcpServer/QTcpSocket instead. Then you could even have some processes running on different machines (or virtual ones). The other - more complicated - option would be to use DBUS. This Server/Socket combination has the advantage that it easily integrates into the signal/slot mechanism of Qt. -- Reinhardt
On Thu, 23 Jun 2016 13:52:21 +0200, pozz wrote:

> I'm new to embedded Linux so this question could be very simple for many > of you. Most probably, it isn't directly related to embedded world, but > to Linux OS generally. Anyway I think it is a common scenario in > embedded applications. > > I'm going to develop a local/remote control of an electronic device. It > communicates through a RS485 link. > The local control will be a touch-screen display (I'm going to use QT > graphic libraries). > The remote control will be HTTP (web server). > > I think a good approach will be to develop a simple application, the > poller, that communicates with the electronic device and implements the > RS485 protocol. The poller continuously acquires the current > status/settings of the device and store them in some "shared" way. > > The graphic application (QT-based) and the web server (CGI) should > access to the data retrieved by the poller. > > What is the best method to share the data generated by an application > (the poller) among two or more applications (QT and CGI)? > In this scenario, I think it's important to lock the "shared data" > before accessing them (reading or writing), in order to avoid reading > incoerent data. Indeed, if the poller writes the data at the same time > (Linux OS is multi-tasking) the web server reads them, they could be > incoerent. > > I'm thinking to use SQLite database to store the data. The poller writes > the database, HTTP and QT reads from it. It seems SQLite will take care > the multi-thread/multi-process scenario. > > Any suggestions?
I did that with System V IPC, using message passing for control and shared memory blocks for info common to all the processes. I was able to avoid any locking using the one-writer/many-readers trick. The code was more low-level than many people, perhaps, would like, but it worked well. Mel.
On 6/23/2016 4:52 AM, pozz wrote:
> I'm new to embedded Linux so this question could be very simple for many of > you. Most probably, it isn't directly related to embedded world, but to Linux > OS generally. Anyway I think it is a common scenario in embedded applications. > > I'm going to develop a local/remote control of an electronic device. It > communicates through a RS485 link. > The local control will be a touch-screen display (I'm going to use QT graphic > libraries). > The remote control will be HTTP (web server). > > I think a good approach will be to develop a simple application, the poller, > that communicates with the electronic device and implements the RS485 protocol. > The poller continuously acquires the current status/settings of the device and > store them in some "shared" way. > > The graphic application (QT-based) and the web server (CGI) should access to > the data retrieved by the poller. > > What is the best method to share the data generated by an application (the > poller) among two or more applications (QT and CGI)? > In this scenario, I think it's important to lock the "shared data" before > accessing them (reading or writing), in order to avoid reading incoerent data. > Indeed, if the poller writes the data at the same time (Linux OS is > multi-tasking) the web server reads them, they could be incoerent. > > I'm thinking to use SQLite database to store the data. The poller writes the > database, HTTP and QT reads from it. It seems SQLite will take care the > multi-thread/multi-process scenario. > > Any suggestions?
It depends on how "lightweight" you want the mechanism to be. And, how "elegant". If you can implement the "Shared Memory" extensions (a kernel option in the *BSD's -- not sure re: Linux) then this is the easiest way forward. Look for shmget(2), shmat(2), shmctl(2), et al. Use a semaphore to control access (and discipline for thereaders/writers to follow that convention) and keep atomic regions short and sweet. If the data isn't changing all that often, you can push it to each consumer through pipes and count on them to keep their own copies intact. (here, there be dragons) The DBMS approach is how I am currently addressing all "persistent data". It's a fair bit heavier-handed (I've got lots of MIPS to spare) but is more elegant; a producer can't inject data into the store unless the data is appropriate for the tables/fields involved (you can't store text somewhere that expects numerics!). Likewise, the consumers need not *check* the data because the checks can be applied on admission to the DB. I.e., if the data is *in* the DB, then you know it satisfied the admission criteria! However, I don't think SQLite has all of these hooks. GNeuner is your go-to guy for the DB approach...
pozz <pozzugno@gmail.com> writes:
> I'm thinking to use SQLite database to store the data. The poller > writes the database, HTTP and QT reads from it. It seems SQLite will > take care the multi-thread/multi-process scenario.
This is the classic and probably easiest approach, though not the most economical in terms of machine use. There are other databases besides sqlite that you can also consider. How much data are you talking about? Do you need stuff like persistence across reboots?
pozz wrote:
> I'm new to embedded Linux so this question could be very simple for many > of you. Most probably, it isn't directly related to embedded world, but > to Linux OS generally. Anyway I think it is a common scenario in > embedded applications. > > I'm going to develop a local/remote control of an electronic device. It > communicates through a RS485 link. > The local control will be a touch-screen display (I'm going to use QT > graphic libraries). > The remote control will be HTTP (web server). > > I think a good approach will be to develop a simple application, the > poller, that communicates with the electronic device and implements the > RS485 protocol. The poller continuously acquires the current > status/settings of the device and store them in some "shared" way. > > The graphic application (QT-based) and the web server (CGI) should > access to the data retrieved by the poller. > > What is the best method to share the data generated by an application > (the poller) among two or more applications (QT and CGI)? > In this scenario, I think it's important to lock the "shared data" > before accessing them (reading or writing), in order to avoid reading > incoerent data. Indeed, if the poller writes the data at the same time > (Linux OS is multi-tasking) the web server reads them, they could be > incoerent. > > I'm thinking to use SQLite database to store the data. The poller writes > the database, HTTP and QT reads from it. It seems SQLite will take care > the multi-thread/multi-process scenario. > > Any suggestions?
1) Qt and HTTP are completely disjoint. Use of Qt is disruptive - it has its own pre-preprocessor and ... keywords specific to Qt. If I could, I would pick one and possibly carve the other off as a separate project. HTTP is, simply put, a bloated, obese protocol which cannot be put on a decent timeline. It's intentionally entanlged with TCP in very unfortunate ways. 2) You mean you will poll for data over an RS485 link, then have two possible clients on a workstation/phone/tablet/whatever that exploit this data. 2a) Is the RS485 link half or full duplex? 2b) If it is half duplex, do you have an accurate model of the line discipline? For example, with MODBUS ( which is 1/2 dux 485 and address muxed ) there will be hard[1] timers to be managed. I recommend a state machine approach. The port cannot be used by more than one request/response pair at a time and response timeouts dominate latency. [1] although they can be made to be adaptive and a select()/poll()/epoll() approach can be quite useful. Much depends on whether the responding node identifies itself in responses. But depending on your serial port architecture, this may get weird. 3) SQLite appears to have locking: https://www.sqlite.org/lockingv3.html 3a) SQL is a bloated pain in the neck. 4) A minimal technology for a shared data store under Linux is shared memory. There are shared memory filesystems or you can develop a shared library/object file which enacts an access protocol for the shared data using the System V primitives. See "System V shmem" and "System V semaphores" through Google for details. This isn't difficult but it's fiddly. It's also the highest performing approach. I;d at least consider guarding the shmem with a semaphore, although I've never established that this is completely necessary 5) Consider using pipes for shared data, possibly. Dunno how you integrate pipes with an HTTP daemon. 6) Sockets are also a good thing to consider using, although again, I have never integrated an HTTP server with sockets for another protocol. Your "poller" offers say, a TCP socket ( to be used over localhost ) and does "multiple unicast" or alternatively actual multicast transmission of the entire data store every so often, or differential ( the things that have changed ) transmission as needed. 6a) Multicast constrains you to the use of UDP. This is a nontrivial project. All this being said, there may be a good software kit to solve this problem out there; I just don't know what it is. and 7) I've seen cases where a COTS HTTP server was used to serve up Java applications to do this. That's kind of old school at this writing. -- Les Cargill
Les Cargill <lcargill99@comcast.com> writes:
> This is a nontrivial project. > All this being said, there may be a good software kit to solve this > problem out there; I just don't know what it is.
I did something like this (TCP over USB between the base unit and the display) and it wasn't so bad. Yes there was a ton of bloaty system code under the surface (language interpreter, network stack etc.) but who cares? The application itself was reasonably simple. The ARM CPU and 64MB of ram were a few dollars, and the "disk" was a 2GB microSD card that was another couple bucks. The user application was written like any other client-server app. The shared data was managed in the application itself, that ran in a single process (multiple threads), but using a database works perfectly well if you don't mind the overhead. If you have the memory for it, Redis could be a good alternative to SQLite, depending on what the application needs.
On Thu, 23 Jun 2016 12:31:55 -0700, Paul Rubin
<no.email@nospam.invalid> wrote:

>pozz <pozzugno@gmail.com> writes: >> I'm thinking to use SQLite database to store the data. The poller >> writes the database, HTTP and QT reads from it. It seems SQLite will >> take care the multi-thread/multi-process scenario. > >This is the classic and probably easiest approach, though not the most >economical in terms of machine use.
SQLite can be run completely in RAM (backed by swap if applicable). Although not possible out-of-the-box, wIth some hacking it can be made to run from a memory mapped file (for persistence).
>There are other databases besides sqlite that you can also consider.
If you have relational data, I believe SQLite is the lightest weight file based RDBMS available. There are a handful of RAM-only libraries that accept SQL-like query languages. If you need only something simple such as key-value pairs, then there are many possible implementations to choose from.
>How much data are you talking about? >Do you need stuff like persistence across reboots?
Excellent questions. George
On 23/06/16 23:05, Reinhardt Behm wrote:
> Jack wrote: >> Il giorno gioved&igrave; 23 giugno 2016 13:52:19 UTC+2, pozz ha scritto: >>> I'm going to develop a local/remote control of an electronic device. It >>> communicates through a RS485 link. >>> I'm thinking to use SQLite database to store the data. The poller writes >>> the database, HTTP and QT reads from it. It seems SQLite will take care >>> the multi-thread/multi-process scenario.
SQLite "takes care of" that by using a single giant lock. That might work for you, since it sounds like you probably have very easy throughput and latency demands. It would be a good solution if you weren't using Qt. Les Cargill hasn't seen how remarkably lightweight SQLite actually is.
> Since you already using Qt, I can propose a solution which I use quite > often. It is even flying in more than 100 helicopters. Yes, penguins can fly > The poller fetches that data from the remote device via RS485 and keeps a > for it local copy. If permanent storage is a requirement it can also take > care of this. > In addition it open a QLocalServer which listens for connections from other > processes. > The other (multiple) processes connect to this server using a QLocalSocket. > They can then poll are are sent the data directly when the poller receives > new data. This way no locking is required since the poller does its sending > in a single thread.
Reinhardt, do you deal with write-blocking if the reader fails? If the write is in the poller thread, any blocking on writes will delay the polling - unless you use non-blocking writes.
> This Server/Socket combination has the advantage that it easily integrates > into the signal/slot mechanism of Qt.
I think it's good advice, though I wouldn't personally have chosen Qt. This application is not demanding enough to need a shared memory solution, with the attendant need for locks and especially, memory barriers, of which most respondents seem ill-educated. In particular, Mel Wilson's "one writer, many reader" is no longer so simple with modern multi-core architectures. Writes do not have to happen in the order they are written, so readers can get confused. Clifford Heath.