Newsgroup: it.comp.lang.c
Titolo: Processo automatico che svuota file

Ciao a tutti,
vi scrivo per avere un suggerimento.
Sto lavorando su di un piccolo dispositivo che dentro di se ha un os linux embedded con una RAM di circa un GB.
Ho messo a punto un piccolo programma che acquisisce dei dati da delle porte che questo dispositivo ha e per essere sufficentemente veloce questi dati acquisiti li scrivo in un file sotto /tmp (in formato binario) che per come è stata configurata l'architettura coincide con la RAM del dispositivo. 
Al crescere della dimensione di questi dati però, le prestazioni del sisema si riducono ed alla fine il processo si arresta prima di quando mi servirebbe.
Quello di cui avrei bisogno, ammesso che esista, è un processo che girasse in background e che appena si accorge della presenza di dati nel file sotto /tmp li sposti in altra area che nel mio caso coinciderebbe con la sd del dispositivo.
 
Quindi la domanda è: C'è la possibilità di accedere contemporaneamente in scrittura e lettura al medesimo file, al fine di poterlo spostare in altra destinazione?
 
Come sempre grazie.


se hai un processo che legge ed un processo che scrive ,le pipe,anche 
con nome,sono un buon modo per procedere
 


Scrivi direttamente sulla SD.
 
Se hai problemi di velocità sull'I/O del processo d'acquisizione, fai fare la
scrittura da un processo in pipe (o un thread) separato, la RAM verrà comunque
usata per il buffer di I/O dal kernel.
 
Oltretutto, se esplode tutto, o se qualcosa si pianta, o qualsiasi altra
condizione per cui devi aspettare un watchdog per riavviare il tutto, almeno
hai traccia di quello che è successo (forse, non è detto, ma hai sicuramente
più possibilità di trovarci qualcosa).
 
Ciao!


come ti e' stato detto: scrivi direttamente su SD e lascia a linux il compito di bufferizzare su RAM.
Ovviamente la SD deve essere abbastanza veloce per gestire il flusso di dati.
 
Se non puoi o non vuoi (perche' devi fare qualcosa con quei dati prima di scriverli su SD) crea 2 files su /tmp, scrivi su uno, quando arriva ad una dimensione prestabilita, inizi a scrivere sul secondo e il primo lo "sposti" sulla SD. Ma ovviamente devi essere sicuro di riuscire a scrivere il file su SD prima che l'altro sia pieno...
 
Ciao Jack


Non ce la fa.
Tieni presente che devo acquisire con una frequenza di 3.84 MHz e dovrei acquisire circa 900 mega byte di dati. Il processo di arresta.
 

 acquisire circa 900 mega byte di dati. Il processo di arresta.
 
Per questo devi usare due processi, uno che acquisice e l'altro che scrive
su SD (per esempio con la pipe di cui sopra).
Il processo che scrive si bloccherà spesso sull'I/O, per cui il processo di
acquisizione può correre senza rallentamenti.
 
Ciao!


allora sei nella merda.
o ci fai stare tutto nella RAM, oppure trovi il modo di scrivere sulla SD abbstanza velocemente.
Come detto, personalmente creerei 2 o piu' files (o se preferisci dei buffer in RAM direttamente nel tuo programma) di dimensione definita e ci scriverei i dati acquisiti sopra in sequenza, quando uno e' pieno inizio a scrivere sul prossimo e salvo sull'SD (anche nello stesso file). Una volta che e' salvato completamente sull'SD lo libero, cosi e' di nuovo utilizzabile per l'acquisizione dati.
 
Cmq quanti byte al secondo devi acquisire?, che e' il dato importante, non mi interessa della quantita' totale o della frequenza di campionamento, perche' se ad esempio acquisisci un byte alla volta ti ritrovi con un throughput di 3,84 MB/sec, che e' gestibilissimo da un SD card.

>...Al crescere della dimensione di questi dati però, le prestazioni del sisema si riducono ed alla fine il processo si arresta
 
Forse dovresti prima cercare di capire perche' questo succede. Da come
hai descritto il sistema credo anche tu abbia capito che stai
'soffocando' il sistema togliendoli la ram disponibile.
 
Visto che l'uso diretto della SD non e` proponibile perche' hai detto
che la velocita` di elaborazione ne risentirebbe, ti consiglierei di
non scrivere nulla su file, i dati te li tieni in memoria (che senso
ha usare un file che usa la memoria? usa direttamente la memoria ed
eviti overhead!), li usi e li scarichi (free) quando non servono piu`.
 
Se ti serve tenere uno storico potresti farei un processo -separato-
(come ti e` gia` stato consigliato) che si occupa solamente di salvare
su SD la memoria prima di farne la free.
-- 
andrea - ri mi cci, name


Devo acquisire circa 30 secondi. I campioni sono complessi dove sia la parte reale sia quella immaginaria sono contenuti su uno short (2byte) di conseguenza un campione occupa 4 byte. Di flussi poi ne devo acquisire 2.
Quindi facendo un rapido conto:
 
3.84e6 * 30 * 4 * 2 = 921.6M Byte.
 
In memoria è improponibile di farcelo stare (in tutto è un GB), quindi devo trovare un qualche meccanismo (pipe, threads con buffer circolare p.e.) che mentre acquisisco in una zona ridotta di RAM, dall'altro lato svuoto su sd altrimenti vale la tua prima espressione :-(

 In memoria è improponibile di farcelo stare (in tutto è un GB), quindi devo trovare un qualche meccanismo (pipe, threads con buffer circolare p.e.) che mentre acquisisco in una zona ridotta di RAM, dall'altro lato svuoto su sd altrimenti vale la tua prima espressione :-(
 
io ti ho detto come fare: crei diversi buffer in ram, li riempi in sequenza e quando sono pieni, li svuoti uno ad uno nella SD. Cosi riesci a riutilizzare almeno parte della ram.
Ma devi vedere a che velocita' riesci a scrivere sulla SD.
 
Ciao Jack


Creati invece una shared ram di dimensione fissa gestita in modo circolare.
Il tuo thread andrà a riempire i dati, un altro thread si occupa
di svuotare e scrivere su SD (in polling o tramite IPC inviata
dal thread di riempimento stesso).
Devi dimensionare la shared ram in funzione della velocita' della SD
in modo da riuscire a svuotarla completamente prima del riempimento:
meglio se con un margine di sicurezza.
aa
 
 

 Ciao a tutti
 
Provare un approccio diverso?
 
Se hai una buona SD potresti mmap-pare su un file e scrivere su quello.
 
La cosa figa di mmap è che hai un pezzo dello spazio di indirizzamento che
pur potendo essere usato come normale memoria, in realtà viene
scritto/letto da un dispositivo di memorizzazione di massa.
 
Fondamentalmente tu scrivi in certi indirizzi di memoria, e il kernel
scrive quello che hai scritto su un file.
Similmente per la lettura.
 
Ovviamente di sotto ci sono algoritmi per il page-in e il page-out, e poi
hai il meccanismo di caching/buffering di Linux.
 
Forse se combini questo con un paio (o più) di threads dovresti farcela.
E dovresti anche riuscire a tenere basso l'utilizzo di memoria.
 
Facci sapere come risolvi, comunque :)
-- 
Emanuele


Grazie dei consigli!
Al momento sto tentando questa strada.
Mi alloco un vettore (doppio) di dimensione pari al numero di campioni che voglio leggere;
poi poiché la lettura viene effettuata su di un numero di campioni che è stato definito ottimale per ogni dispositivo: num_samps_per_buffer (ne ho due ed hanno questo valore differente), definisco un puntatore che punta all'inizio del vettore e tale puntatore lo passo alla routine che acquisisce i dati.
In questa maniera vengono copiati nel vettore i primi num_samps_per_buffer.
A questo punto faccio avanzare il puntatore di num_samps_per_buffer posizioni ed effettuo un'altra lettura, etc.
 
Ossia sto tentando la strada "i dati li mantengo in RAM".
 
Sebbene questo approccio semplifichi la vita (non ho bisogno di threads o pipe), sto verificando una limitazione che è legata alla massima memoria utilizzabile. Con una RAM disponibile di 1 GB, non riesco ad allorare più di 70 milioni di campioni che corrispondono a 560 mega byte (70000000 * 2 * 4 => 2 sono le catene ed ogni elemento è un complex che occupa 2byte per RE e 2 byte per IM). Oltre questo limite mi riporta l'errore bad-alloc.
 
A questo punto vi chiedo: possibile che non riesca ad allocare che un po' più della metà della memoria disponibile?
 
Esiste una limitazione teorica nei buffer allocabili?
 
Il mio obbiettivo sarebbe arrivare circa ad 800 mega byte lasciandone 200 al sistema operativo ed al programma che gira.
 
E' una follia? Magari c'è un limite teorico che ignoro. Tutto questo perché arrivato a tale valore, allora potrei adottare la strategia dei multi-threads per riuscire ad acquisire il numero di campioni che realmente mi serve.
 
Grazie