2009-06-06 37 views
6

優先二郎收到如下可以很容易地實現:二郎:優先接收

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

我讀了一個名爲Priority Messaging made Easy中,他們描述了以下問題紙:

與存在的主要問題上面的[代碼]例子是,我們沒有考慮到當從內部阻塞接收恢復評估時,我們可能在郵箱中有多條消息。在最壞的情況下,除了第一個可能是大量元素之外的所有元素都可能成爲優先消息。在這種情況下,我們實際上已經完成了與我們打算做的事情完全相反的事情。

我不完全明白這一點。

問題(1):我假定內阻擋接收將是「稱爲」(即恢復)只要一個消息已經到達在消息隊列中,是嗎?假設在短時間內從內部阻塞接收恢復過來,現在已經有一大堆消息在隊列中等待了嗎?

問題(2):另外,最壞的情況被描述爲一個正常消息和很多優先消息的隊列。由於所有的接收子句都是先對照隊列中的第一條消息進行檢查,然後再對照隊列中的第二條消息進行檢查......(來源:此book,第69-70頁)不應該是這樣:很多正常消息隊列末尾有優先消息嗎?

回答

5

Erlang是一種完全同步的語言,沒有理由不能在同一時間發送幾條消息。按照「哦,這很快 - 其他線程不太可能在這麼短的時間內發生衝突是很不可能的」這樣的假設基本上與閉上你的眼睛並說「沒有比賽條件這樣的事情是一回事,沒有比賽條件......「

+4

不要忘記點擊你的紅寶石拖鞋。 – 2009-06-06 16:53:04

4

關於(1):這個假設是否可以取決於你的情況的細節。例如,所有其他進程可能在發送消息之前一直等待發生。

關於(2):實際上,在我看來,最糟糕的情況是沒有優先級消息,因爲每次都必須遍歷郵箱:「是否還有優先級消息?

1

根據erlang參考手冊按時間順序接收遍歷郵箱。並阻塞,直到消息符合條款之一。

鑑於它聽起來像內部接收器將阻止,直到它收到一個匹配的消息。正因爲如此,您可能會在等待非優先級消息時堆疊優先級消息,而這與您想要的相反。

擺脫這種困境的辦法是在內部接收方面拋出一個新的後續條款。或者總是在內部接受匹配。

雖然看着他們的功能,內在的條款應該總是匹配,但我猜這就是他們正在談論的。

0

你的亮點是簡單地說,如果你是在阻止內部接收塊,你可以一個高優先級的消息之前處理低優先級的消息(因爲你是匹配的一切),這是不一定的意圖聲明。

這是一個有點邊緣情況的 - 我發現,在被處理消息高效,當你需要一些類型的過濾是很重要的。在其他情況下,我也監視了流程隊列深度並相應地改變了我的策略。作爲後者的簡單記錄gen_server型過程(使用了投射到發送日誌消息)的一個例子可以得到相當備份爲寫日誌消息到磁盤可以比推出這些消息的過程慢很多。如果隊列深度過大,我會丟棄通常會記錄的信息/垃圾郵件類型的消息,並只處理(寫入磁盤)關鍵的消息。