2010-08-27 78 views
77

與線程相比,演員的工作方式有什麼好的和簡短的解釋嗎?與線程相比,Actors如何工作?

無法將線程看作是actor並將消息發送給其他線程?我看到一些差異,但對我來說並不那麼清楚。我可以通過使用不同的線程在任何語言中使用演員嗎?

回答

62

演員模型運行消息傳遞。各個進程(參與者)被允許相互異步地發送消息。與通常認爲的線程模型不同的是,(至少在理論上)沒有共享狀態。如果有人相信(理所當然,我認爲)共享狀態是萬惡之源,那麼演員模型就會變得非常有吸引力。

但是,我們不應該過度興奮。演員模型不(與一些指控相反)使得不可能發生死鎖。參與者模型也不會阻止您在不同進程之間爭用資源 - 例如,消息隊列。該模型僅在一定水平之上「無鎖」。在較低級別上,爲了協調消息隊列,仍然需要鎖定。

無法將線程看作是actor並將消息發送給其他線程?

嗯,是的,沒有。不,如果您只是使用將互斥鎖放在共享內存位置的方法。然後這些線程共享這個狀態 - 它們都可以訪問這個內存,既可以讀取它,也可以重寫它,等等。但是你可以在線程模型之上構建一個actor模型,並且實際上所有的actor實現都有線程下。我通過給每個線程一個由互斥鎖守護的隊列一起黑客攻擊(非常糟糕),這只是爲了好玩。要了解演員線程阻抗如何管理,請參閱my question from a year ago

我可以通過不同的線程使用任何語言的Actor模型嗎?

是的,但它需要更多的工作。你最喜歡的語言可能有一個消息傳遞庫,所以這將是第一個要調查的東西。另外,您應該研究不可變數據結構的使用。注意,如果數據結構是不可變的,那麼你基本上已經處理了「共享狀態」問題 - 多個線程可以持有對不可變數據的引用,而不會發生任何不良情況。演員語言也傾向於是功能語言(erlang,scala)是有原因的。

您可能還想看看Software Transactional Memory,它是一種不同但又引人注目的模型。 Clojure是我最喜歡的例子。

+2

我越使用異步消息傳遞基於併發模型(例如演員或異步/等待),越我認爲它們只是雙舊,標準同步阻斷併發模型的。異步消息傳遞並不比使用鎖和監視器更容易或更難。事實上,沒有共享的可變狀態,但僅限於*單演員級別*。但是演員仍然具有可變狀態,並且實際上可以由所有與之合作的演員觀察到。因此,您可能會遇到同樣的問題:死鎖,活鎖,飢餓,競爭條件等。 – 2015-12-04 07:46:38

2

我不會說演員總是異步地傳遞消息 - 這太慢了。例如,JActor項目使用雙向消息(請求/響應)來更好地建模方法調用。並且大多數請求是同步服務的。

JActor(一個Java庫)也不使用鎖。只有一些原子和併發的數據結構,只有少量信號量被拋入。消息傳遞大約是每秒8億條消息。

https://github.com/laforge49/JActor

+1

actor模型僅使用異步通信(http://en.wikipedia.org/wiki/Actor_model)進行定義。如果JActor沒有這樣做,那麼它不是100%只有演員模型。它可以簡單地使用演員模型作爲其中的一個特徵。 – 2012-12-24 21:36:27