Perché usare una pipa denominata anziché un file?


42

Di recente ho letto delle pipe nominate e non riuscivo a capire perché esistessero.
Ho letto da qualche parte che l'utilizzo di una named pipe richiede meno tempo rispetto all'utilizzo di un file.

Perché è così?
Le pipe nominate devono anche essere archiviate in memoria (e forse scambiate, proprio come i file).
Per quanto posso vedere, devono ottenere un inode a cui deve fare riferimento la directory corrente, proprio come i file. Inoltre, devono essere rimossi dal programmatore, proprio come i file.

Allora, dove sta il vantaggio?


Questo non fa parte di un compito in classe, vero?
don.joey

6
no ... in realtà stavo guardando alcuni appunti delle lezioni quando ho trovato questa domanda e non ho potuto rispondere ... e se fosse un compito, non vedo come sarebbe rilevante ... non è come Non avrei cercato la risposta fino a quando non l'avrei trovata
user3122885,

Risposte:


41

Quasi tutto in Linux può essere considerato un file , ma la differenza principale tra un file normale e una pipe con nome è che una pipe con nome è un'istanza speciale di un file che non ha contenuti sul filesystem.

Ecco la citazione da man fifo:

Un file speciale FIFO (una pipe denominata) è simile a una pipe, tranne per il fatto che è accessibile come parte del filesystem. Può essere aperto da più processi per la lettura o la scrittura. Quando i processi scambiano dati tramite FIFO, il kernel passa internamente tutti i dati senza scriverli nel filesystem. Pertanto, il file speciale FIFO non ha contenuti sul filesystem; la voce del filesystem funge semplicemente da punto di riferimento in modo che i processi possano accedere alla pipe usando un nome nel filesystem.

Il kernel mantiene esattamente un oggetto pipe per ogni file speciale FIFO che viene aperto da almeno un processo. Il FIFO deve essere aperto su entrambe le estremità (lettura e scrittura) prima che i dati possano essere passati. Normalmente, aprendo i blocchi FIFO fino all'apertura dell'altra estremità.

Quindi in realtà una named pipe non fa nulla fino a quando qualche processo non legge e scrive su di essa. Non occupa spazio sul disco rigido (tranne un po 'di meta informazioni), non utilizza la CPU.

Puoi verificarlo facendo questo:

Crea una pipa denominata

$ mkfifo /tmp/testpipe

Vai ad alcune directory, ad esempio /home/user/Documents, e gzip tutto al suo interno, usando il nome pipe.

$ cd /home/user/Documents
$ tar cvf - . | gzip > /tmp/testpipe &
[1] 28584

Qui dovresti vedere il PID del processo gzip. Nel nostro esempio era 28584.

Ora controlla cosa sta facendo questo PID

$ ps u -P 28584
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
c0rp     28584  0.0  0.0  29276  7800 pts/8    S    00:08   0:00 bash

Vedrai che non utilizza risorse . 0% di utilizzo della CPU, 0% di utilizzo della memoria.

Verifica la comprensione dell'utilizzo dello spazio file

$ du -h /tmp/testpipe
0   testpipe

E ancora 0niente. Il testpipe può essere riutilizzato se necessario.

Non dimenticare di uccidere gzip, usando kill -15 28584. E rimuovi la nostra pipa denominata usandorm /tmp/testpipe

Esempi di utilizzo

Puoi reindirizzare quasi tutto utilizzando la pipe denominata. Ad esempio puoi vedere questo proxy a una riga .

Anche qui c'è un'altra bella spiegazione sull'uso della pipe con nome. È possibile configurare due processi su un server per comunicare utilizzando una pipe denominata anziché lo stack TCP / IP. È molto più veloce e non carica risorse di rete. Ad esempio, il tuo server Web può comunicare direttamente con il database utilizzando una pipe denominata, anziché utilizzare l' localhostindirizzo o ascoltare una porta.


14

È vero che non utilizzerai la memoria di sistema, ma il fatto che non usi cpu nel tuo esempio è solo perché non leggi la pipe, quindi il processo è in attesa.

Prendi in considerazione il seguente esempio:

mkfifo /tmp/testpipe
tar cvf - / | gzip > /tmp/testpipe

Ora apri una nuova console ed esegui:

watch -n 1 'ps u -P $(pidof tar)

E in una terza console:

cat /tmp/testpipe > /dev/null

Se guardi l'orologio cmd (2o termine) mostrerà un aumento del consumo di CPU!


1
Questa risposta riguarda la risposta di
c0rp

2

Ecco un caso d'uso in cui le named pipe possono farti risparmiare molto tempo rimuovendo l'I / O.

Supponiamo che tu abbia un BigFile, ad esempio 10G.

Hai anche divisioni di questo BigFile in pezzi di 1G, BigFileSplit_01 in BigFile_Split_10.

Ora hai dei dubbi sulla correttezza di BigFileSplit_05

Ingenuamente, senza named pipe, crei una nuova divisione da BigFile e confronti:

dd if=BigFile of=BigFileSplitOrig_05 bs=1G skip=4 count=1
diff -s BigFileSplitOrig_05 BigFileSplit_05
rm BigFileSplitOrig_05

Con le pipe nominate faresti

mkfifo BigFileSplitOrig_05
dd if=BigFile of=BigFileSplitOrig_05 bs=1G skip=4 count=1 &
diff -s BigFileSplitOrig_05 BigFileSplit_05
rm BigFileSplitOrig_05

A prima vista potrebbe non sembrare una grande differenza ... ma col tempo la differenza è enorme!

Opzione 1:

  • dd: leggi 1G / scrivi 1G (1)
  • diff: leggi 2G
  • rm: cluster allocati gratuitamente / rimuovi la voce della directory

Opzione 2:

  • dd: niente! (va alla named pipe)
  • diff: leggi 2G
  • rm: nessun cluster allocato da gestire (in realtà non abbiamo scritto nulla nel filesystem) / rimuovere la voce della directory

Quindi sostanzialmente la pipe denominata ti salva qui una lettura e scrittura di 1G più un po 'di pulizia del filesystem (dal momento che non abbiamo scritto nulla sul filesystem tranne il vuoto quindo nodo).

Non eseguire l'I / O, in particolare le scritture, è anche utile per evitare l'usura dei dischi. È ancora più interessante quando lavori con gli SSD poiché hanno un numero limitato di scritture prima che le cellule muoiano.

(1) Ovviamente, un'altra opzione sarebbe quella di creare quel file temporaneo su RAM, ad esempio se / tmp è montato su RAM (tmpfs). Tuttavia si sarebbe limitati dalle dimensioni del disco RAM, mentre il "trucco della pipa denominata" non ha limiti.


1

Puoi lasciare fermo un programma e ascoltare una pipe denominata per qualche evento esterno. Non appena si verifica l'evento esterno (ad esempio l'arrivo di alcuni nuovi dati), questo potrebbe essere rilevato da qualche altro programma che a sua volta apre la pipe per la scrittura, scrivendo i relativi dati dell'evento nella pipe. Quando viene emessa l'istruzione close, il programma di ascolto riceverà il flusso di dati attraverso la pipe tramite un'istruzione read ed è pronto per elaborare ciò che ha. Non dimenticare di chiudere il tubo dopo aver letto il contenuto. Il programma di ascolto potrebbe anche restituire i risultati della sua elaborazione tramite lo stesso o tramite un'altra pipe denominata. Talvolta tali comunicazioni tra programmi sono molto convenienti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.