簡體   English   中英

了解scala中actor的線程性

[英]understanding threadedness of actors in scala

我被告知(Scala)Actors實際上從不實際執行兩個操作,這表明該行為(或反應?或接收?)方法本質上是同步的。 我知道一個act方法中的長操作會導致阻塞問題,我認為必須以某種方式同步對消息隊列的訪問......但是......

建議的是,接收消息告訴它增加內部計數器的actor將以線程安全的方式遞增計數器。 不會同時處理兩條更新消息,因此沒有兩條消息可以同時嘗試更新計數器。

演員中的計數器屬性聽起來像“共享狀態”。

這樣的操作是完全線程安全的嗎? 如果是這樣,演員如何以一種有效的方式使用多個核心機器? 演員如何多線程?

如果沒有,那么以線程安全方式計算消息而不需要某些synchronized / volatile變量的適當慣用方法是什么?

Actor模型可用於將可變狀態與外界隔離。 當您具有可變狀態(例如,分配給多個並發進程的ID的全局注冊表)時,您可以將該可變狀態包裝在Actor內部並使客戶端通過消息傳遞與Actor通信。 這樣只有actor直接訪問可變狀態,正如你所說,客戶端消息排隊等待逐個讀取和處理。 消息是不可變的很重要。

為了避免隊列變滿,重要的是消息處理( reactreceive等)盡可能短。 長期運行的任務應交給其他演員:

1.  Actor A receives a message M from sender S
2.  A spawns a new actor C
3.  A sends (S, f(M)) to C
4.  In parallel:
4a. A starts processing the next message.
4b. C does the long-running or dangerous (IO) task,
    When finished, sends the result to S,
    and C terminates.

該過程中的一些替代方案:

  • C發送(S, result)回A轉發給S
  • A保持映射ActorRef C => (Sender S, Message M) 以便在看到C失敗時 ,它可以使用新的Actor重試處理M.

所以回顧一下,一個Actor是多線程的,多個客戶端可以從各個線程發送多個消息,並保證Actor將串行處理所有這些消息(盡管排序可能受到各種非過度的影響)嚴格約束)。

請注意,雖然Actor的react代碼可以在各種線程上執行 ,但是在一個給定的時間點它只在一個給定的線程上執行(你可以想象一下,當調度程序認為合適時,Actor會從一個線程跳轉到另一個線程,但是這是技術細節)。 注意:內部狀態仍然不需要同步,因為Actors 保證在處理消息之間的語義之前發生

並行性是通過讓多個Actors並行工作來實現的,通常形成管理層次結構平衡工作負載

請注意,如果您只需要並發/異步計算,但您沒有或可以擺脫全局狀態,則Future是一個更好的組合和更簡單的概念。

“演員”不是多線程的,但演員系統通常是。 每個actor一次只執行一個動作,但是當有多個actor時,每個actor可以並行地在其各自的封裝狀態下操作。 如果不在actor之間共享則counter屬性不是共享可變狀態。

如果您的問題是關於actor系統的實現,那么它可以變化並且通常是可配置的,即默認的Scala actor可以配置為運行單線程或線程池或使用Java ForkJoin任務。 我發現scala.actors源代碼非常易讀,所以如果你想了解發生了什么,我建議看看。

您可以使用單獨的actor來進行計數。 當演員獲得消息時,它可以向(單身)計數演員發送消息。 這樣,您可以擁有多個worker actor並仍然可以計算消息。

Akka有一些叫做Agents東西,在這種情況下可能很有用。

val counter = Agent(0)
counter send (_ + 1)

http://doc.akka.io/docs/akka/2.0.2/scala/agents.html

暫無
暫無

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

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