2009-06-08 18 views
50

Ho giocato con code di messaggi (System V, ma anche POSIX va bene) in Linux di recente e sembrano perfetti per la mia applicazione, ma dopo aver letto The Art of Unix Programming non sono sicuro che siano davvero un bella scelta.Le code dei messaggi sono obsolete in linux?

http://www.faqs.org/docs/artu/ch07s02.html#id2922148

La parte superiore, passaggio di messaggi strato di System V IPC ha ampiamente caduti in disuso. Il livello inferiore, costituito da memoria condivisa e semafori, presenta ancora applicazioni significative in circostanze in cui è necessario eseguire il blocco dell'esclusione reciproca e una condivisione di dati globali tra processi in esecuzione sulla stessa macchina. Queste strutture di memoria condivisa System V si sono evolute nell'API di memoria condivisa POSIX, supportate da Linux, BSD, MacOS X e Windows, ma non da MacOS classico.

http://www.faqs.org/docs/artu/ch07s03.html#id2923376

Le strutture System V IPC sono presenti in Linux e altri Unix moderni. Tuttavia, poiché sono una funzione legacy, non vengono esercitati molto spesso. La versione Linux è ancora nota per avere bug a partire dalla metà del 2003. A nessuno sembra importare abbastanza per risolverli.

Le code di messaggi System V sono ancora buggate nelle versioni Linux più recenti? Non sono sicuro che l'autore significhi che le code dei messaggi POSIX dovrebbero essere ok?

Sembra che i socket siano l'IPC preferito per quasi tutto (?), Ma non riesco a vedere come sarebbe molto semplice implementare code di messaggi con socket o altro. O sto pensando in modo troppo complesso?

Non so se è rilevante il fatto che sto lavorando con Linux incorporato?

risposta

56

Personalmente sono abbastanza appassionato di code di messaggi e penso che siano probabilmente l'IPC meno utilizzato nel mondo Unix. Sono veloci e facili da usare.

Un paio di pensieri:

  • Alcune di queste è solo moda. Le cose vecchie diventano di nuovo nuove. Aggiungi un brillante do-dad alle code dei messaggi e potrebbero essere la cosa più nuova e più calda dell'anno prossimo. Guarda Google Chrome utilizzando processi separati anziché thread per le sue schede. All'improvviso le persone sono entusiaste del fatto che quando una scheda si blocca, non fa cadere l'intero browser.

  • La memoria condivisa ha qualcosa di aureola di He-man su di esso. Non sei un programmatore "reale" se non riesci a spremere l'ultimo ciclo dalla macchina e gli MQ sono marginalmente meno efficienti. Per molte, se non per la maggior parte delle app, è una sciocchezza totale, ma a volte è difficile rompere una mentalità una volta che prende piede.

  • MQ non sono davvero adatti per applicazioni con dati illimitati. Meccanismi orientati al flusso come tubi o prese sono solo più facili da usare per questo.

  • Le varianti System V sono davvero andate male. Come regola generale, vai con le versioni POSIX di IPC quando puoi.

+0

7 anni dopo .. speriamo che non sia troppo per essere ancora abbastanza rilevante: mi chiedo le impostazioni predefinite delle code di messaggi su 'Ubuntu 14.04',' linux 3.13', ovvero 'cat/proc/sys/fs/mqueue/msg_max' elenca 10 (messaggi in una coda) e'/proc/sys/fs/mqueue/msgsize_max' è 8192 (byte) - sono stranamente piccoli. C'è qualche ragione rigida per queste impostazioni predefinite o sono solo vecchie? (L'uomo mq_overview' dice che hard limit su msg_max è circa 32768, che è piuttosto alto.) Non intendo creare una coda infinita simile a stream, ma è 100-1000 in 'msg_max' ok? – xealits

10

In realtà non ho usato le code di messaggi POSIX perché voglio sempre lasciare aperta l'opzione per distribuire i miei messaggi su una rete. Con questo in mente, si potrebbe guardare un'interfaccia di trasmissione dei messaggi più robusta come zeromq o qualcosa che implementa AMQP.

Uno degli aspetti positivi di 0mq è che quando viene utilizzato dallo stesso spazio di processo in un'app con multithreading, utilizza un meccanismo di zero-copy lockless che è abbastanza veloce. Tuttavia, è possibile utilizzare la stessa interfaccia per passare anche i messaggi su una rete.

11

Sì, penso che le code di messaggi siano appropriate per alcune applicazioni. Le code di messaggi POSIX forniscono un'interfaccia più gradevole, in particolare, è possibile fornire i nomi delle code anziché gli ID, il che è molto utile per la diagnosi degli errori (rende più facile vedere quale è).

Linux consente di montare le code di messaggi posix come un filesystem e vederle con "ls", cancellarle con "rm" che è abbastanza comodo (System V dipende dai clunky comandi "ipcs" e "ipcrm")

+0

Questa funzione è disponibile anche per socket Datagram UNIX. Posso legare il socket di datagramma a un file e ricevere lo stesso modo della coda dei messaggi POSIX. Posso persino usare 'netcat' per inviare i dati di test al file socket del datagramma. – shuva

1

più grandi svantaggi di coda di messaggi POSIX:. coda di messaggi

  • POSIX non lo rendono un requisito per essere compatibile con select() (funziona con select() in Linux, ma non nel sistema QNX)
  • Ha sorprese.

Un socket di Datagram Unix svolge la stessa funzione della coda di messaggi POSIX. E socket Datagram Unix funziona in socket layer. È possibile utilizzarlo con select()/poll() o altri metodi di attesa IO. L'utilizzo di select()/poll() ha il vantaggio quando si progetta un sistema basato su eventi. È possibile evitare il loop di occupato in questo modo.

C'è una sorpresa nella coda dei messaggi. Pensa a mq_notify(). È usato per ricevere l'evento di ricezione. Sembra che possiamo comunicare qualcosa sulla coda dei messaggi. Ma in realtà si sta registrando per la notifica invece di notificare nulla.

Ulteriori sorpresa per mq_notify() è che deve essere chiamato dopo ogni mq_receive(), che può causare una gara condizionata (quando qualche altra chiamata processo/thread mq_send() tra la chiamata di mq_receive() e mq_notify()).

E ha un'intera serie di con una propria definizione che è ridondante e in alcuni casi incoerente con le specifiche del metodo socket open(),send(),recv() and close().

Non penso che la coda dei messaggi debba essere utilizzata per la sincronizzazione. eventfd e signalfd sono adatti per questo.

Ma ha qualche supporto in tempo reale. Ha caratteristiche prioritarie.

Messages are placed on the queue in decreasing order of priority, with newer messages of the same priority being placed after older messages with the same priority. 

Ma questa priorità è disponibile per presa come out-of-band dei dati anche!

Infine, per me, la coda di messaggi POSIX è un'API legacy. Preferisco sempre il socket Datagram di Unix invece della coda dei messaggi POSIX.

Problemi correlati