Lavorando su hardware relativamente a bassa velocità, ho bisogno di catturare un'istantanea di un flusso di dati in rapida evoluzione e quindi post-elaborare i dati dell'istantanea e salvarli su disco.
Ho bisogno di aiuto per progettare l'approccio generale dato i vincoli di elaborazione dall'hardware.
La fase snapshot deve essere completata in modo relativamente istantaneo, perché blocca il flusso di dati mentre esegue l'acquisizione. Credo di voler eseguire questo come un processo separato, o almeno come thread stand-alone. Questa fase deve essere data la priorità per l'elaborazione e l'accesso alle risorse.
La fase post-elaborazione si basa su librerie esterne che non utilizzano un modello di chiamata di funzione / API ripetuta-iterazione. Sarebbe in grado di limitare la velocità di chiamata di - invece, una singola funzione la chiamata esegue l'intera operazione.
Tuttavia, non mi interessa quando finiscono queste attività di post-elaborazione, e preferirei che questa routine venisse eseguita in modo tale da funzionare per CPU / IO molto piccole durante il funzionamento. Il mio pensiero è che ciò incoraggerebbe gli eventi futuri dello snapshot per completare con un minimo di latenza. La post-elaborazione impiega solo pochi secondi per essere completata, ma la priorità è maggiore della latenza dello snapshot rispetto alla velocità di post-elaborazione.
Tenendo conto di tutti questi requisiti, per me è logico eseguire entrambe queste azioni come attività concorrenti separate e dire al kernel che l'attività di snapshot ha una priorità estremamente elevata e che l'attività post-processo ha una priorità estremamente bassa .
Generalmente dico task qui, e ho detto "concurrent" nel titolo, perché non sono sicuro se voglio usare processi separati per questo, o implementare qualche forma di multi-threading .
Ho solo una piccola esperienza con fork()
e simili, e non ho esperienza con il threading, quindi ho alcune domande su come / dove dovrei iniziare:
-
Quale metodo sarebbe preferibile - thread o processi separati? L'utilizzo dei thread semplifica la condivisione dell'accesso alla memoria tra le due attività?
-
Posso impostare la pianificazione del kernel / priorità IO quando utilizzo i thread? O mi preoccupo troppo dell'impostazione della priorità del kernel a questo punto?
-
Per mantenere il processo di snapshot veloce, sarebbe ideale che l'attività di snapshot lasci semplicemente i dati da elaborare seduti in memoria affinché l'attività di post-processo venga ripresa ed eseguita, quindi l'attività di istantanea è immediatamente chiara e aspettando il prossimo evento. Questo sembra essere meglio affrontato con un approccio di accodamento, ma non so se ci sono approcci che forniscono altri vantaggi.
Se stavo usando fork()
, potrei semplicemente lasciare i dati non elaborati in una pipe()
per l'attività post-processo da ripulire dopo. Sono sicuro che il pipe non si riempirà e bloccerà il processo di snapshot.
Non sono sicuro di cosa posso fare con il threading. Potrei eventualmente allocare memoria dal thread di snapshot; condividere i puntatori tramite IPC; allora free()
i dati dal thread post-processo? Guadagno velocità di elaborazione o altri benefici adottando questo approccio?
Per aiutare a focalizzare la mia domanda, ho due vasti percorsi che sto considerando.
-
Due processi separati che utilizzano la funzionalità
pipe()
del SO per fornire comunicazione tra di loro. -
Un processo multi-thread che utilizza IPC o altri meccanismi di comunicazione.
Devo essere in grado di assegnare la priorità a un'attività sull'altra e probabilmente su altri processi in esecuzione sul sistema. Ho dei limiti di tempo per l'esecuzione di una delle attività, ma non mi interessa il tempo di esecuzione per la seconda attività.
I miei due percorsi potenziali sono equivalenti, oppure c'è un approccio preferito dato i miei vincoli? O c'è un terzo approccio che è meglio di quei due?