2009-06-06 17 views
6

Priorytet otrzymują w Erlang można łatwo wdrożyć w następujący sposób:Erlang: priorytet otrzymują

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

Czytam gazetę o nazwie Priority Messaging made Easy, w którym opisują następujący problem:

Głównym problemem [kod] przykład [powyżej] jest taki, że nie bierzemy pod uwagę, że gdy wznowienie oceny następuje z wewnętrznego odbioru blokowania, możemy mieć więcej niż jedną wiadomość w skrzynce pocztowej. W najgorszym przypadku wszystkie, oprócz pierwszej potencjalnie dużej liczby elementów, mogą być komunikatami priorytetowymi. W tym scenariuszu osiągnęlibyśmy wręcz przeciwieństwo tego, co zamierzaliśmy zrobić.

Nie do końca rozumiem.

Pytanie (1): Zakładam, że wewnętrzna blokowanie odbierać będzie „nazywa się” (tj wznowione) jak tylko jeden wiadomość dotarła w kolejce komunikatów, prawda? Czy jest realistycznym założenie, że w krótkim czasie, jaki zajmuje wznowienie z wewnętrznego odbierania blokującego, w kolejce czekałaby już cała masa wiadomości?

Pytanie (2): Również najgorszy scenariusz opisany jest jako kolejka z jednym zwykłym komunikatem i wieloma komunikatami o priorytecie. Ponieważ wszystkie klauzule odbierania są najpierw sprawdzane przed pierwszą wiadomością w kolejce, a następnie przed drugą wiadomością w kolejce ... (źródło: to book, strona 69-70) nie powinno to być: dużo normalnego komunikaty z na końcu kolejki komunikat priorytetowy?

Odpowiedz

5

Erlang to radykalnie równoległy język, nie ma powodu, aby nie można było wysłać kilku wiadomości w tym samym czasie. Przyjmowanie założeń w stylu: "Och, to jest szybkie - jest tak mało prawdopodobne, że inne wątki zrobiłyby coś, co będzie konfliktować w tak krótkim czasie" jest zasadniczo tym samym, co zamknięcie oczu i powiedzenie "Nie ma czegoś takiego jak warunki wyścigu, jest nie ma czegoś takiego jak warunki wyścigu ... "

+4

Nie zapomnij o kliknięciu klapek z rubinem. –

4

Włącz (1): To, czy to założenie może zostać dokonane zależy od szczegółów twojej sytuacji. Na przykład wszystkie inne procesy mogły czekać, aż coś się wydarzy, zanim wyślesz swoje wiadomości.

On (2): W rzeczywistości, wydaje mi się, że w najgorszym przypadku będzie żadnych wiadomości priorytetowych, jak skrzynka musiałby być wykonywany za każdym razem: „ma wiadomość priorytet nadejść w”

1

Zgodnie z instrukcją obsługi erlanga, otrzyma skrzynkę pocztową w kolejności czasowej. i blokuje, aż wiadomość pasuje do jednej z klauzul.

Biorąc pod uwagę, że wygląda na to, że wewnętrzna wiadomość zostanie zablokowana, dopóki nie otrzyma pasującej wiadomości. Z tego powodu możesz w rzeczywistości umieszczać wiadomości priorytetowe w oczekiwaniu na wiadomości niepriorytetowe, które są przeciwieństwem tego, co chcesz.

Zbytnie wyjście z tej sytuacji rzuca nową klauzulę after na wewnętrzny odbiór. Lub zawsze dopasuj się w wewnętrznym odbiorze.

Chociaż patrząc na ich funkcję, wewnętrzna klauzula powinna zawsze być zgodna, ale domyślam się, że właśnie o tym rozmawiali.

0

Podkreślenie, które zaznaczyłeś, mówi po prostu, że jeśli jesteś w blokującym wewnętrznym bloku odbierającym, możesz przetworzyć komunikat o niskim priorytecie przed wiadomością o wysokim priorytecie (ponieważ dopasowujesz wszystko), co niekoniecznie jest intencją.

To drobna sprawa - przekonałem się, że skuteczne przetwarzanie komunikatów, gdy zależy Ci na pewnym rodzaju filtrowania, jest ważne. W innych przypadkach monitorowałem także kolejkę procesów i odpowiednio zmieniłem strategię. Jako przykład tego ostatniego, prosty proces logowania typ_serwera (który został użyty do przesyłania wiadomości dziennika) może uzyskać raczej kopię zapasową, ponieważ zapisywanie komunikatów dziennika na dysku może być znacznie wolniejsze niż wysyłanie wiadomości do procesu. Gdyby głębokość kolejki była zbyt duża, odrzuciłbym komunikaty informacyjne/typu spam, które normalnie logowałbym i przetwarzały tylko te krytyczne (zapis na dysku).