2009-06-06 20 views
6

Priorità ricevere in Erlang può essere facilmente implementata come segue:Erlang: priorità ricevere

prio() -> 
    receive 
    {priority, X} -> X 
    after 0 -> 
    receive 
     X -> X 
    end 
    end. 

Sto leggendo un articolo intitolato Priority Messaging made Easy in cui essi descrivono il seguente problema:

Il problema principale con l'esempio [codice] [sopra], è che non prendiamo in considerazione il fatto che quando la valutazione viene ripresa dalla ricezione del blocco interno potremmo avere più di un messaggio nella casella di posta. Nel peggiore dei casi, tutti tranne il primo, potenzialmente un numero enorme di elementi potrebbero essere messaggi prioritari. In questo scenario avremmo effettivamente realizzato esattamente l'opposto di ciò che intendevamo fare.

Non lo capisco completamente.

questione (1): Suppongo che il blocco interno riceve verra 'chiamato' (vale a dire riprende) non appena uno messaggio è arrivato nella coda dei messaggi, giusto? È realistico supporre che nel breve lasso di tempo necessario per riprendere dalla ricezione interna di blocco, ci sarebbe già un sacco di messaggi in attesa in coda?

Domanda (2): Inoltre, lo scenario peggiore è descritto come una coda con un messaggio normale e molti messaggi prioritari. Poiché tutte le clausole di ricezione vengono prima verificate rispetto al primo messaggio in coda, e quindi contro il secondo messaggio in coda, ... (fonte: questo book, pagina 69-70) non dovrebbe essere questo: un sacco di normale messaggi con alla fine della coda un messaggio prioritario?

risposta

5

Erlang essendo un linguaggio radicalmente concorrente, non c'è motivo per cui non sia possibile che siano stati inviati diversi messaggi allo stesso tempo. Fare assunzioni sulla falsariga di "Oh, questo è veloce - è così improbabile che gli altri thread possano fare qualcosa che confligge in quel poco tempo" è essenzialmente la stessa cosa che chiudere gli occhi e dire "Non esiste una cosa come le condizioni di gara, c'è nessuna cosa come condizioni di gara ... "

+4

Non dimenticare di fare clic sulle tue pantofole Ruby. –

4

On (1): se questa ipotesi può essere fatta dipende dai dettagli della vostra situazione. Ad esempio, tutti gli altri processi potrebbero aver aspettato che qualcosa accadesse prima di inviarti i loro messaggi.

On (2): In realtà, mi sembra che il caso peggiore sarebbe non messaggi di priorità, come la casella di posta dovrebbe essere percorsa ogni volta: "ha un messaggio di priorità ancora arrivato"

1

In base al manuale di riferimento di erlang, la ricezione attraversa la casella di posta in ordine cronologico. e blocca fino a quando un messaggio corrisponde a una delle clausole.

Dato che sembra che il ricevitore interno bloccherà finché non riceverà un messaggio corrispondente. Per questo motivo potresti effettivamente accumulare messaggi prioritari in attesa di messaggi non prioritari che sono l'opposto di ciò che desideri.

Troppe uscite da questa situazione stanno lanciando una nuova clausola post sulla ricezione interna. O sempre abbinare nel ricevitore interno.

Anche se osservando la loro funzione, la clausola interna dovrebbe sempre coincidere, ma immagino che questo sia ciò di cui stavano parlando.

0

L'affermazione evidenziata indica semplicemente che se si sta bloccando il blocco di ricezione interno è possibile elaborare un messaggio con priorità bassa prima di un messaggio con priorità alta (poiché si sta verificando tutto) che non è necessariamente l'intento.

È un caso marginale: ho scoperto che essere efficienti nell'elaborare i messaggi quando si desidera un tipo di filtro è importante. In altri casi ho anche monitorato la profondità della coda del processo e modificato di conseguenza la mia strategia. Come esempio di quest'ultimo, un semplice processo di tipo gen_server di logging (che usava il cast per inviare il messaggio di log) potrebbe essere piuttosto sottoposto a backup poiché la scrittura dei messaggi di log sul disco può essere molto più lenta di quella di inviare i messaggi al processo. Se la profondità della coda diventasse troppo grande, eliminerei i messaggi di tipo informativo/spam che normalmente registrerei e elaborerei solo (scrivendo su disco) quelli critici.