2010-06-11 40 views

回答

9

如果我們認爲演員是人,那麼消息就像......消息。

說一個老闆想要平方根的數字列表a,並不想做所有計算himeself。他可以僱用一些工人,老闆會知道他們的電話號碼。

所以老闆會短信給每個工人,告訴他們「找到a_i的平方根;完成後回覆我555-1234」。該指令是消息。老闆將等待工人完成。

+------+ sqrt(i=0, a_i=9)   +------------+ 
| Boss | ------------------------> | Worker 0 | 
+------+       +------------+ 
     | sqrt(i=1, a_i=16)  +------------+ 
     ‘--------------------------> | Worker 1 | 
            +------------+ 
             .... 

工作人員完成計算後,他們會發送短信給老闆並報告結果。這也是在消息傳遞中完成的。

+------+ set_result(i=0, val=3) +------------+ 
| Boss | <------------------------ | Worker 0 | 
+------+       +------------+ 
    ^set_result(i=1, val=4) +------------+ 
     ‘--------------------------- | Worker 1 | 
            +------------+ 
             .... 

這聽起來像面向對象的編程,但目前還沒有以其中當消息被髮送或接收的 - 它們被傳遞異步。 (然而,演員本身內,消息被接收並同步地排隊。)

當寫入代碼,它可以是像

actor Boss: 
    receive('run'): 
    worker_addrs = spawn_many(SqrtWorker, len(a)) # hire workers. 
    for i, addr in enumerate(worker_addrs): 
     send(addr, 'sqrt', reply_addr=self, i=i, a_i=a[i]) 

    receive('set_value', i, val): 
    a[i] = val 

actor SqrtWorker: 
    receive('sqrt', reply_addr, i, a_i): 
    send(reply_addr, 'set_value', i, sqrt(a_i)) 
    quit() 

不存在「共享狀態問題」,因爲一個狀態不能在沒有複製的情況下共享。在我上面的例子中,列表a的元素是複製給每個工人。事實上,只有老闆知道a的存在 - 這是一個本地狀態

現在如果我們真的想讓a共享?在演員模型中,我們會將它們轉換爲新演員,並將此演員的電話號碼發送給工作人員。

+------+ sqrt(i=0, a_phoneNum=555-1111) +----------+ 
| Boss | -------------------------------> | Worker 0 | 
+------+         +----------+ 

      +---+ 
      | a | 
      +---+ 

工人然後問列表演員的所需信息(這是可能的,因爲老闆給的a的電話號碼給工人。)

+------+         +----------+ 
| Boss |         | Worker 0 | 
+------+         +----------+ 
               | 
      +---+        | 
      | a | <---------------------------’ 
      +---+    get(i=0) 

一段時間後,該列表回覆...

+------+         +----------+ 
| Boss |         | Worker 0 | 
+------+         +----------+ 
              ^
      +---+  list_val(i=0, val=9) | 
      | a | ----------------------------’ 
      +---+ 

然後工人可以接收到該消息後list_val計算平方根。

+------+  set_result(i=0, val=3)  +----------+ 
| Boss | <------------------------------ | Worker 0 | 
+------+         +----------+ 

      +---+ 
      | a | 
      +---+ 

老闆終於更新共享狀態

+------+         +----------+ 
| Boss |         | Worker 0 | 
+------+         +----------+ 
    | set(i=0, val=3)     
    |  +---+ 
    ‘------> | a | 
      +---+ 

是否有訪問這樣的共享狀態的任何問題?不可以 - 由於a收到的消息必須同步運行,所有讀/寫操作都將互相干擾。因此不需要混淆互斥體。