第五章 Actor
5.1 更加面向?qū)ο?/h3>
函數(shù)式編程不使用可變狀態(tài),也就避免了共享可變狀態(tài)帶來(lái)的問(wèn)題鳍刷。相比之下喇伯,使用actor模型保留了可變狀態(tài),只是不進(jìn)行共享颊糜。
Elixir是Erlang的虛擬機(jī)哩治。actor在Elixir中被稱為進(jìn)程,是個(gè)輕量級(jí)的概念衬鱼,比操作系統(tǒng)中的線程還要輕业筏。
5.2 第一天:消息和信箱
第一個(gè)actor
先來(lái)嘗試創(chuàng)建一個(gè)簡(jiǎn)單的actor,并向其發(fā)送一些消息鸟赫。我們將創(chuàng)建一個(gè)叫talker的actor蒜胖,其收到不同的消息時(shí)會(huì)輸出不同的結(jié)果。所發(fā)送的消息是一個(gè)元組(tuple)惯疙。
def module Talker do
def loop do
recevie do
[:greet, name] -> IO.puts("Hello ${name}")
[:praise, name]->IO.puts("#{name}, you're amazing")
[:celebrate, name, age]->IO.puts("Here's to another #{age} years, #{name}")
end
loop
end
end
pid = spawn(8Talker.loop/0)
send(pid, [:greet, "World"])
send(pid, ["praise", "Dewey"])
send(pid, [:celebrate, "Louie", 16])
sleep(1000)
spawn創(chuàng)建actor實(shí)例,并獲得進(jìn)程標(biāo)識(shí)符妖啥。
隊(duì)列式信箱
消息并不是直接發(fā)送到一個(gè)actor霉颠,而是發(fā)送到一個(gè)信箱。發(fā)送消息時(shí)不會(huì)被阻塞荆虱。actor按照信箱接收消息的順序來(lái)一次處理消息蒿偎,且僅在當(dāng)前消息處理完成后才會(huì)處理下一個(gè)消息朽们,因此我們只需要關(guān)心發(fā)消息時(shí)的并發(fā)問(wèn)題即可。
接收消息
通常actor會(huì)進(jìn)行無(wú)限循環(huán)诉位,通過(guò)recevice等待接收的消息骑脱,看上面的代碼中該函數(shù)通過(guò)遞歸調(diào)用實(shí)現(xiàn)無(wú)限循環(huán),那么可能有人會(huì)問(wèn)這樣不會(huì)造成棧溢出嗎苍糠?與許多函數(shù)式語(yǔ)言一樣叁丧,Elixir實(shí)現(xiàn)了尾調(diào)用的消除。為調(diào)用消除指的是如果函數(shù)在最后調(diào)用了自己岳瞭,那么遞歸調(diào)用將被替換成一個(gè)簡(jiǎn)單的跳轉(zhuǎn)拥娄。
為了徹底關(guān)閉一個(gè)actor,需要滿足兩個(gè)條件瞳筏。一個(gè)是需要告訴actor在完成消息處理之后關(guān)閉稚瘾;第二個(gè)是需要知道actor合適完成關(guān)閉。
def module Talker do
def loop do
recevie do
[:shutdown] -> exit(:normal)
end
loop
end
end
send(pid, [:shutdown])
有狀態(tài)的actor
雙向通信
actor模型沒有提供直接回復(fù)消息的機(jī)制姚炕,但我們可以自行解決:將發(fā)送進(jìn)程的標(biāo)識(shí)符包含在消息中摊欠。通過(guò)這個(gè)機(jī)制,消息的接受者可以回復(fù)消息柱宦。
5.3 第二天:錯(cuò)誤處理和容錯(cuò)性
并發(fā)很重要的一個(gè)特性是并發(fā)代碼具有容錯(cuò)性些椒。
在大多數(shù)語(yǔ)言中,唯一的處理方法是添加一些檢查參數(shù)的代碼捷沸,當(dāng)檢查到非法參數(shù)時(shí)報(bào)錯(cuò)摊沉。Elixir提供了另外一種方法--將錯(cuò)誤處理隔離到一個(gè)管理進(jìn)程中,這個(gè)方法看似簡(jiǎn)單痒给,確是一個(gè)很大的改進(jìn)说墨,使代碼更簡(jiǎn)潔、更具維護(hù)性苍柏,也更可靠尼斧。
錯(cuò)誤檢測(cè)
任其崩潰
防御式編程主要通過(guò)預(yù)言可能出現(xiàn)的缺陷來(lái)實(shí)現(xiàn)容錯(cuò)。使用actor模型的程序并不進(jìn)行防御式編程试吁。而是遵循了任其崩潰的哲學(xué)棺棵。
第六章 通信順序進(jìn)程
6.1 萬(wàn)物皆通信
通訊順序進(jìn)程(Communicating Sequential Process, CSP)模型,與actor類型熄捍,也是由獨(dú)立的烛恤,并發(fā)的執(zhí)行的實(shí)體所組成,實(shí)體之間也是通過(guò)發(fā)送消息進(jìn)行通信余耽。但兩種模型的最重要差別是:CSP模型不關(guān)注發(fā)送消息的實(shí)體缚柏,而是關(guān)注發(fā)送消息時(shí)使用的channel。
數(shù)據(jù)并行
7.1 隱藏在筆記本電腦中的超級(jí)計(jì)算機(jī)
圖形處理單元GPU碟贾,是一個(gè)強(qiáng)力的數(shù)據(jù)并行處理器币喧,其用于數(shù)學(xué)計(jì)算時(shí)性能超過(guò)CPU轨域,這種做法成為基于圖形處理器的通用計(jì)算(GPGPU編程)。
7.2 第一天:GPGPU編程
圖形處理與數(shù)據(jù)并行
3D游戲的一個(gè)場(chǎng)景是由無(wú)數(shù)個(gè)小三角形構(gòu)成的杀餐,每一個(gè)三角形都需要根據(jù)與視點(diǎn)相關(guān)的透視關(guān)系計(jì)算出其在屏幕上的位置干发,并進(jìn)行裁剪,處理光照史翘,修改紋理等枉长,這些操作每秒鐘需要進(jìn)行25次以上。
雖然需要處理的數(shù)據(jù)量是巨大的恶座,但其有一個(gè)非常好的特性:施加在數(shù)據(jù)上的操作都是相對(duì)簡(jiǎn)單的向量操作或矩陣操作搀暑。因此這種場(chǎng)景非常適合數(shù)據(jù)并行。
數(shù)據(jù)并行可以通過(guò)多種方法來(lái)實(shí)現(xiàn)跨琳,我們要學(xué)習(xí)其中的兩種:流水線和對(duì)ALU自点。