簡體   English   中英

為什么演員收到的消息是無序的?

[英]Why are messages received by an actor unordered?

我一直在研究actor模型(特別是Scala中的實現)但我無法理解為什么要求消息沒有按特定順序到達。

似乎至少有一些優雅的,基於actor的並發問題解決方案,只有消息按順序到達時才會起作用(例如,生產者 - 消費者變體,延遲數據庫寫入,並發安全緩存)。

那么為什么演員的消息沒有按順序到達? 它是允許有效實現還是可以防止在訂購消息時出現某種死鎖?

我的印象是,如果兩個線程向一個演員a發送一條消息,則沒有特別保證演員首先接收到哪一個。 但是如果你有代碼看起來像

a ! "one"
a ! "two"

那么a總是會在"two" "one"之前得到"one" (雖然誰知道其他線程之間可能還有什么)。

因此,我不認為消息根本沒有特定的順序。 來自一個線程內的多條消息(根據我從代碼或經驗中可以看出)將按順序到達。

我不知道為什么Scala的Actors(標准庫中的那些,無論如何 - 還有Aka的Akka,Lift和Scalaz實現)選擇了這個特定的實現。 可能是Erlang自身限制的副本 - 但沒有兩個單線程之間通信的保證。 或許也有這種保證 - 我希望Phillip Haller在這里發表評論。

但是,我確實質疑你關於並發問題的陳述。 在研究異步分布式算法時,一個基本原則是您不能保證任何消息接收順序

引用Hagit Attiya和Jennifer Welch的分布式計算:基礎,模擬和高級主題

如果對於消息傳遞所花費的時間或處理器的連續步驟之間經過了多長時間沒有固定的上限,則稱系統是異步的。

actor模型是異步模型。 這使它能夠在分布式硬件上工作 - 無論是通過網絡進行通信的不同計算機,還是不提供同步保證的系統上的不同處理器。

此外,甚至多核處理器上的多線程模型也大多是異步的,其中同步的原語非常昂貴。

所以問題的簡單答案可能是:

消息不能保證按順序到達,因為這是異步系統的基本限制,異步系統是actor使用的基本計算模型。

這個模型是我們在任何通過TCP / IP分布的系統上實際擁有的模型,也是i386 / x64多核/多處理器硬件上最高效的模型。

以下簡單示例顯示了按順序到達非常簡單的actor的消息:

import scala.actors._
import scala.actors.Actor._
import scala.collection.mutable._

val adder = actor {
  loop {
    react {
      case x: Int => println(" Computing " + x); reply(x+2)
      case Exit => println("Exiting"); exit
    }
  }
}

actor {
  for (i <- 1 to 5) {
    println("Sending " + i)
    adder !! (i, { case answer => println("Computed " + i + " -> " + answer) })
  }

  println("Sending Exit")
  adder !! Exit
}

以下是使用Sun JDK 1.6.0u25在Windows 64位上使用Scala 2.9.0 final的上述代碼的一次運行的輸出:

Sending 1
Sending 2
Sending 3
Sending 4
Sending 5
Sending Exit
 Computing 1
Computed 1 -> 3
 Computing 4
Computed 4 -> 6
 Computing 3
Computed 3 -> 5
Exiting

你會選擇什么樣的訂單? 應該是在他們被送去還是收到他們的時候? 在我們對郵件進行排序時,我們應該凍結整個郵箱嗎? 想象一下,對一個大而近乎完整的郵箱進行排序,是否會對隊列進行任意鎖定? 我認為消息沒有按順序到達,因為沒有保證執行此類訂單的方法。 我們在網絡和處理器之間存在延遲。

我們不知道消息來自哪里,只知道它們已經到達。 那么這個怎么樣,我們保證我們沒有訂購,甚至沒有考慮訂購。 我們可以專注於盡可能保持爭用,而不是必須提出一些令人印象深刻的邏輯來保持組織有序,同時盡可能保持無爭用。

其他人可能比我對此有更好的答案。

編輯:

現在我已經有時間睡覺了,我認為這是一個規定,允許創建一個更有活力的Actor生態系統。 因此,為什么要從線程池中限制一個Actor或一個線程或線程的部分所有權? 如果有人希望擁有一個可以盡可能多地獲取線程的Actor來盡可能多地處理其郵箱中的郵件,該怎么辦?

如果您事先做出規定,消息必須按照他們繼續進行的順序完成,那么您永遠無法允許這樣做。 可以由Actor分配多個線程來處理郵箱中的郵件,您將無法控制首先處理哪個郵件。

Phew,你的夢想在你睡覺時對你的思想所說的話。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM