FIFO (la named pipe) ostacoli di messaggistica
-
06-09-2019 - |
Domanda
Ho in programma di utilizzare le pipe Unix nome (mkfifo) per semplice messaggistica multi-processo. Un messaggio potrebbe essere solo una singola riga di testo.
Me lo scoraggiare da questo? Quali ostacoli mi devo aspettare?
ho notato queste limitazioni:
- Un mittente non può continuare fino alla ricezione del messaggio.
- Un ricevitore è bloccato fino ci sono alcuni dati. Non bloccante IO sarebbe necessaria quando abbiamo bisogno di fermare la lettura. Ad esempio, un altro thread potrebbe chiedere per questo.
- Il ricevitore potrebbe ottenere molti messaggi in una sola lettura. Questi devono essere elaborati prima quiting.
- La lunghezza massima di un messaggio atomica è limitata da 4096 byte. Questo è il limite PIPE_BUF su Linux (vedi man 7 pipe).
I attuerà la messaggistica in Python. Ma gli ostacoli tengono in generale.
Soluzione
- La mancanza di portabilità - sono principalmente una cosa Unix. Prese sono più portabile.
- Più difficile da scalare su più sistemi (un'altra prese +)
- D'altra parte, ritengo tubi sono più veloci di prese per processi sulla stessa macchina (meno overhead comunicazione).
Per quanto riguarda i tuoi limiti,
- È possibile " selezionare " su tubi, per fare una lettura non-blocking .
- I normalmente (in Perl) stampare i miei messaggi su tubi separati da "\ n", e leggere una linea da loro per ottenere un messaggio alla volta.
- Fare attenzione con la lunghezza atomica.
perlipc essere un buona discussione tra le varie opzioni, anche se ha un codice specifico perl.
Altri suggerimenti
Il blocco, sia sul lato mittente e il lato ricevitore, può essere risolto con non-blocking I / O.
Ulteriori limitazioni di FIFO:
- Un solo cliente alla volta.
- Dopo che il client chiude la FIFO, il server ha bisogno di ri-aprire il suo endpoint.
- unidirezionale.
UNIX invece, che hanno nessuna delle limitazioni di cui sopra.
Come ulteriore vantaggio, se si vuole scalare per comunicare tra più macchine, è a malapena qualsiasi cambiamento a tutti. Ad esempio, basta prendere la pagina di documentazione di Python su presa e sostituire socket.AF_INET
con socket.AF_UNIX
, (HOST, PORT)
con filename
, e solo funziona .
SOCK_STREAM
vi darà un comportamento stream-simili; cioè, due manda possono essere fusi in uno di ricezione o viceversa. AF_UNIX
supporta anche SOCK_DGRAM
: datagrammi sono garantiti da inviare e leggere tutti come una sola unità o per niente. (Analogamente, AF_INET
+ SOCK_STREAM
= TCP, AF_INET
+ SOCK_DGRAM
= UDP.)