Michele Liberi software

versione 1.04, giugno 2026

Michele Liberi
mail: mliberi@gmail.com
cell: +393485211456
telegram: @MicheleLiberi

liberix

afifo, gestione asincrona code fifo

In ambiente UNIX esiste una struttura nativamente gestita del kernel per la gestione delle code FIFO (first-in first-out): la named pipe. Tale struttura svolge egregiamente la sua funzione quando la comunicazione avviene in modalità sincrona, ovvero quando il programma che genera il flusso di dati ed il programma che lo deve ricevere girano contemporaneamente.

Esiste però l'esigenza applicativa di disaccoppiare il processo che genera il dato dal processo che legge il dato per elaborarlo. L'uno deve poter girare indipendemente dall'altro in modalità asincrona.

Il sistema UNIX non ha comandi o system call per questo genere di comunicazione, ma esistono prodotti commerciali che forniscono questa funzionalità. Ricordiamo, uno per tutti, IBM MQ Manager, un sistema multipiattaforma per la gestione delle code.

Anche il database Redis con i sottocomandi LPUSH e BLPOP consente di gestire code FIFO.

Entrambi i su citati sistemi hanno delle controindicazioni. IBM MQ è complesso da installare e da gestire, inoltre prevede il pagamento di licenze per il suo utilizzo. D'altro canto Redis, pur liberamente installabile, è facilmente utilizzabile solo in ambiente Linux e non è disponibile, ad esempio, in IBM AIX.

Per superare queste limitazioni ho deciso di costruire un mio sistema molto semplice per la gestione delle code asincrone, che consta di un unico eseguibile (generato da un sorgente scritto in C) che può essere installato su tutti i sistemi UNIX e anche in ambiente Windows.

Nasce così il comando afifo che consente di gestire l'equivalente delle code locali di MQM. Non ho ritenuto necessario costruire l'equivalente delle code remote in quanto è possibile estendere il concetto della coda locale a quello della coda remota usando il comando rxc (cfr.).

Il file di configurazione /etc/afifo.conf contiene i seguenti parametri:

fifodir pathname
la directory base che contiene i file dove vengono fisicamente salvati i messaggi in attesa che qualcuno li prelevi. Tale parametro può essere indicato anche direttamente a linea di comando con l'opzione -I'dir'. Se questo parametro non viene valorizzato il comando afifo farà riferimento alla directory corrente. In ogni caso il nome della coda può essere un pathname assoluto.
logdir pathname
la directory dove vengono salvati i log file, uno per ogni coda, che contengono la registrazione di tutte le operazioni che sono state effettuate sulla coda. Non è un parametro obbligatorio, se manca non verrà registrato alcun log. Per ogni coda verrà creato un file del tipo afifo.nomecoda.log. Tale parametro può essere indicato anche direttamente a linea di comando con l'opzione -L'dir'. Per inciso questa è una funzionalità che manca nel sistema IBM MQM.
umask octal
Si tratta di un numero ottale (in base 8) che viene passato alla omonima funzione di libreria standard del C (mode_t umask(mode_t mask);). Determina i permessi che vengono assegnati ad un nuovo file o directory che viene creato dal processo. In questo contesto si applica:

Non esiste un comando per la creazione di una coda, essa viene creata automaticamente e dinamicamente nel momento in cui viene referenziata per la prima volta.

Non esiste neanche un comando per la cancellazione di una coda. Per cancellare una coda basta rimuovere l'omonimo file nella directory fifodir, e opzionalmente il corrispondente file di log nella directory logdir.

Con il termine messaggio in questo contesto si intende un blocco di bytes arbitrariamente lungo (binary bytestream).

Il comando afifo accetta i seguenti sottocomandi:

put
Scrive un singolo messaggio nella coda. Il messaggio viene letto da standard input. La stessa identica azione si ottiene con l'alias add.
puts msg
Scrive un singolo messaggio nella coda. Il messaggio viene passato al comando direttamente come argomento.
get [timeout]
Preleva un messaggio dalla coda e lo scrive su standard output. La stessa identica azione si ottiene con l'alias pop. Se il timeout non viene specificato il comando afifo rimane in attesa di un messaggio a tempo indeterminato. Se il timeout è zero il comando afifo preleva il messaggio solo se immediatamente disponibile. Se il timeout è maggiore di zero indica il numero massimo di secondi di attesa.
getall
Preleva tutti i messaggi dalla coda e li scrive su standard output. Non è prevista attesa di nuovi messaggi, il comando preleva solo quelli già presenti in coda.
clear
Cancella tutti i messaggi dalla coda.
view
Legge un messaggio dalla coda e lo scrive su standard output. A differenza del comando get il comando view non modifica la coda, il messaggio rimane in coda. Non è prevista attesa, il messaggio viene letto solo se immediatamente disponibile.
viewall
Legge tutti i messaggi presenti in coda e li scrive su standard output. Non è prevista attesa di nuovi messaggi, il comando preleva solo quelli già presenti in coda. La coda non viene modificata, i messaggi letti rimangono in coda.
list
Genera su standard output una lista dei messaggi in coda, una riga per messaggio, con le seguenti informazioni:
depth
Scrive su standard output la profondità della coda, ovvero il numero di messaggi in coda. La stessa identica azione si ottiene con gli alias count e n.
lastput
Scrive su standard output il timestamp dell'ultima put che è stata fatta sulla coda.
lastget
Scrive su standard output il timestamp dell'ultima get che è stata fatta sulla coda.
codici di ritorno del comando afifo
rcerroredescrizione
9syntax error il comando è stato richiamato in modo sintatticamente errato
8can't chdir non è stato possibile entrare nella directory indicata dal parametro fifodir
7not a regular file il file associato alla coda esiste, ma non è un file regolare
6can't read non è stato possibile aprire la coda in read-only
5invalid header il file associato alla coda non contiene un header valido, non è una coda creata con il comando afifo
4can't write mancano i permessi di scrittura sul file associato alla coda; il permesso di scrittura è necessario solo per i comandi che effettivamente modificano la coda
2write error tipicamente si ottiene questo errore quando il comando put o puts cerca di scrivere un messaggio nella coda senza riuscirci
1empty queue si ottiene questo errore quando si cerca di leggere un messaggio da una coda che non contiene messaggi
0successful il comando è andato a buon fine

Per ulteriori informazioni sulla sintassi di attivazione e sulle opzioni disponibili lanciare il comando con l'opzione -h.

(c) M. Liberi, last updated: 2026-06-15