莊周夢(mèng)蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理







          posted @ 2010-05-23 05:53 dennis 閱讀(867) | 評(píng)論 (0)編輯 收藏


          1、首先態(tài)度需要端正,做代碼的自我審查并不是否定自己,而是給自己將工作做得更好的一次機(jī)會(huì)。在審查過程中要盡量將自己作為一個(gè)旁觀者的心態(tài)去審查自己的代碼,盡管這比較困難。

          2、代碼審查離不開重構(gòu),在審查過程中發(fā)現(xiàn)任何壞味道都請(qǐng)使用重構(gòu)去改善,發(fā)現(xiàn)缺乏測(cè)試的地方要及時(shí)補(bǔ)充測(cè)試,不要讓BUG遺漏。

          3、代碼的自我審查可能不是越早越好,隔一段時(shí)間之后回去看自己寫的東西,對(duì)一些設(shè)計(jì)上的選擇能有更客觀的評(píng)價(jià),在審查的過程中可能需要重新去理解代碼,在此過程中可以檢查自己代碼的可讀性,并思考如何改善可讀性,切記代碼首先是給人讀的

          4、審查過程中需要記錄下一些犯下的錯(cuò)誤,以及當(dāng)時(shí)為什么會(huì)犯下這樣的錯(cuò)誤,建立自己的bug數(shù)據(jù)庫,并時(shí)常review,在以后的工作中避免同樣的錯(cuò)誤。

          5、代碼的自我審查應(yīng)該是一個(gè)持續(xù)性的過程,而非特定時(shí)間的特定行動(dòng),時(shí)常審查自己的代碼,不僅能辨析自己的得失,還能夠進(jìn)一步提高自己在未來工作中的設(shè)計(jì)能力和預(yù)見能力。

          6、代碼的自我審查跟團(tuán)隊(duì)成員之間的相互review并不矛盾,在相互review之前做一個(gè)自我審查,有助于提高review的效率,包括可讀性的提高和一些一般錯(cuò)誤的避免。

          7、代碼自我審查的一些常見注意點(diǎn):
          (0)自認(rèn)為絕不會(huì)出錯(cuò),并且從來沒有審查過的代碼。
          (1)注意else語句,if條件下的子語句通常可能是個(gè)正常的流程,而else意味著異常的情況或者特殊的場(chǎng)景,你可能特別注意怎么處理正常的情況,卻忽略了else子句的實(shí)現(xiàn)細(xì)節(jié),如該釋放的鎖沒釋放,該遞減的計(jì)數(shù)沒有遞減,該賦予特殊值卻沒有賦予等等。
          (2)注意空的方法,沒有方法體的方法,是不需要實(shí)現(xiàn)?還是忘了實(shí)現(xiàn)?
          (3)注意switch語句,有沒有忘了break?這種錯(cuò)誤通過findbugs之類的靜態(tài)代碼檢查工具都能避免。
          (4)注意大塊的注釋,為什么這么多注釋?是代碼寫的很糟糕?還是遺留的注釋?遺留的注釋會(huì)誤導(dǎo)人,要及時(shí)刪除。
          (5)注意一些看起來“不合常理”的代碼,這樣的代碼很多都是基于所謂性能考慮而優(yōu)化過的代碼,這樣的優(yōu)化是否還需要?是否能去除這些“奇怪”的代碼也能實(shí)現(xiàn)正常的需求?
          (6)對(duì)客戶端的使用有假設(shè)的代碼,假設(shè)用戶只會(huì)這么用,假設(shè)用戶只會(huì)用到返回對(duì)象中的某些屬性,其他屬性一定不會(huì)用到?不要對(duì)客戶代碼做假設(shè)!這個(gè)客戶代碼包括外部用戶和調(diào)用這個(gè)模塊的內(nèi)部代碼。
          (7)標(biāo)注了FIXME、TODO之類task標(biāo)簽的代碼,是否忘了修復(fù)BUG,實(shí)現(xiàn)功能?
          (8)任何超過15行以上的方法,這些方法是否能拆分成更細(xì)粒度的方法,并保持在同一個(gè)抽象層次上?
          (9)任何在代碼中出現(xiàn)的常量值,是否應(yīng)該提取出來成為單獨(dú)的常量,常量的默認(rèn)值設(shè)置是否合理?
          (10) 任何持有容器的代碼,提供了放入容器的方法,是否提供了從容器中移除對(duì)象的方法?確保沒有內(nèi)存泄漏的隱患。
          (11)重構(gòu)中提到的其他壞味道,別放過它們,但是也不要追求完美,OO不是圣杯,如果能簡(jiǎn)單的實(shí)現(xiàn)一個(gè)算法,你不要引入3個(gè)對(duì)象和4個(gè)接口。
          (12)在review最后能列出一張清單,開列下該項(xiàng)目面臨的風(fēng)險(xiǎn)點(diǎn),并提出解決辦法,然后按照這張清單去review關(guān)鍵代碼,著重檢查異常情況下的處理。風(fēng)險(xiǎn)點(diǎn)的review,我建議可以放在后面,在一般性錯(cuò)誤解決之后進(jìn)行,此時(shí)你對(duì)代碼也將再度變的熟悉。

          posted @ 2010-05-18 00:28 dennis 閱讀(6417) | 評(píng)論 (4)編輯 收藏

              笑死我了


          posted @ 2010-04-29 18:54 dennis 閱讀(1269) | 評(píng)論 (1)編輯 收藏

             
              Ruby Fiber指南(一)基礎(chǔ)
              Ruby Fiber指南(二)參數(shù)傳遞
              Ruby Fiber指南(三)過濾器
              Ruby Fiber指南(四)迭代器
              Ruby Actor指南(五)實(shí)現(xiàn)Actor

              寫這個(gè)指南的時(shí)候,計(jì)劃是第五章寫一個(gè)Fiber的應(yīng)用例子,但是一時(shí)沒有想到比較好的例子,模仿《Programming in Lua》中的多任務(wù)下載的例子也不合適,因?yàn)镽uby中的異步HttpClient跟lua還是很不一樣的,體現(xiàn)不了Fiber的優(yōu)點(diǎn)。因此,這第五節(jié)一直拖著沒寫。
              恰巧最近在小組中做了一次Erlang的分享,有人問到Erlang調(diào)度器的實(shí)現(xiàn)問題,這塊我沒注意過,那時(shí)候就根據(jù)我對(duì)coroutine實(shí)現(xiàn)actor的想法做了下解釋,后來思考了下那個(gè)解釋是錯(cuò)誤的,Erlang的調(diào)度器是搶占式的,而通過coroutine實(shí)現(xiàn)的actor調(diào)度卻是非搶占的,兩者還是截然不同的。我在《Actor、Coroutine和Continuation的概念澄清》中提到coroutine可以實(shí)現(xiàn)actor風(fēng)格,actor跟coroutine并沒有必然的聯(lián)系,這篇文章的目的就在于證明這一點(diǎn),使用Ruby Fiber實(shí)現(xiàn)一個(gè)簡(jiǎn)單的actor風(fēng)格的庫,整個(gè)代碼不到100行。后面還會(huì)談到這個(gè)實(shí)現(xiàn)的缺點(diǎn),以及我對(duì)Erlang調(diào)度器實(shí)現(xiàn)的理解。

              首先是monkey patch,給Thread和Fiber類加上兩個(gè)方法,分別用于獲取當(dāng)前線程的調(diào)度器和Fiber對(duì)應(yīng)的actor:
          class Thread
            
          #得到當(dāng)前線程的調(diào)度器
            def __scheduler__
              @internal_scheduler
          ||=FiberActor::Scheduler.new
            end
          end

          class Fiber
            
          #得到當(dāng)前Fiber的actor
            def __actor__
              @internal_actor
            end
          end

               這里實(shí)現(xiàn)的actor仍然是Thread內(nèi)的,一個(gè)Thread只跑一個(gè)調(diào)度器,每個(gè)actor關(guān)聯(lián)一個(gè)Fiber。
               讓我們來想想調(diào)度器該怎么實(shí)現(xiàn),調(diào)度器顧名思義就是協(xié)調(diào)actor的運(yùn)行,每次挑選適當(dāng)?shù)腶ctor并執(zhí)行,可以想象調(diào)度器內(nèi)部應(yīng)該維護(hù)一個(gè)等待調(diào)度的actor隊(duì)列,Scheduler每次從隊(duì)列里取出一個(gè)actor并執(zhí)行,執(zhí)行完之后取下一個(gè)actor執(zhí)行,不斷循環(huán)持續(xù)這個(gè)過程;在沒有actor可以調(diào)度的時(shí)候,調(diào)度器應(yīng)該讓出執(zhí)行權(quán)。因此調(diào)度器本身也是一個(gè)Fiber,它內(nèi)部有個(gè)queue,用于維護(hù)等待調(diào)度的actor:
          module FiberActor
            
          class Scheduler
              
          def initialize
                @queue
          =[]
                @running
          =false
              end

              
          def run
                
          return if @running
                @running
          =true
                
          while true
                  
          #取出隊(duì)列中的actor并執(zhí)行
                  while actor=@queue.shift
                    begin
                      actor.fiber.resume
                    rescue 
          => ex
                      puts 
          "actor resume error,#{ex}"
                    end
                  end
                  
          #沒有任務(wù),讓出執(zhí)行權(quán)
                  Fiber.yield
                end
              end

              
          def reschedule
                
          if @running
                  
          #已經(jīng)啟動(dòng),只是被掛起,那么再次執(zhí)行
                  @fiber.resume
                
          else
                  
          #將當(dāng)前actor加入隊(duì)列
                  self << Actor.current
                end
              end

              
          def running?
                @running
              end

              
          def <<(actor)
                
          #將actor加入等待隊(duì)列
                @queue << actor unless @queue.last == actor
                
          #啟動(dòng)調(diào)度器
                unless @running
                   @queue 
          << Actor.current
                   @fiber
          =Fiber.new { run }
                   @fiber.resume
                end
              end
            end
          end

              run方法是核心的調(diào)度方法,注釋說明了主要的工作流程。因?yàn)檎{(diào)度器可能讓出執(zhí)行權(quán),因此提供了reschedule方法重新resume啟動(dòng)調(diào)度器。<<方法用于將等待被調(diào)度的actor加入等待隊(duì)列,如果調(diào)度器沒有啟動(dòng),那么就啟動(dòng)調(diào)度Fiber。

              有了調(diào)度器,Actor的實(shí)現(xiàn)也很簡(jiǎn)單,Actor跟Fiber是一對(duì)一的關(guān)系,Actor內(nèi)部維護(hù)一個(gè)mailbox,用來存儲(chǔ)接收到的消息。最重要的是receive原語的實(shí)現(xiàn),我們這里很簡(jiǎn)單,不搞模式匹配,只是接收消息。receive的工作流程大概是這樣,判斷mailbox中有沒有消息,有消息的話,取出消息并調(diào)用block處理,沒有消息的話就yield讓出執(zhí)行權(quán)。

          module FiberActor  
            
          class Actor
              attr_accessor :fiber
              
          #定義類方法
              class << self
                
          def scheduler
                  Thread.current.
          __scheduler__
                end

                
          def current
                  Fiber.current.
          __actor__
                end

                
          #啟動(dòng)一個(gè)actor
                def spawn(*args,&block)
                  fiber
          =Fiber.new do
                     block.call(args)
                  end
                  actor
          =new(fiber)
                  fiber.instance_variable_set :@internal_actor,actor
                  scheduler 
          << actor
                  actor
                end

                
          def receive(&block)
                  current.receive(
          &block)
                end
              end

              
          def initialize(fiber)
                 @mailbox
          =[]
                 @fiber
          =fiber
              end

              
          #給actor發(fā)送消息
              def << (msg)
                @mailbox 
          << msg
                
          #加入調(diào)度隊(duì)列
                Actor.scheduler << self
              end

              
          def receive(&block)
                
          #沒有消息的時(shí)候,讓出執(zhí)行權(quán)
                Fiber.yield while @mailbox.empty?
                msg
          =@mailbox.shift
                block.call(msg)
              end

              
          def alive?
                @fiber.alive?
              end
            end

          end

              Actor.spawn用于啟動(dòng)一個(gè)actor,內(nèi)部其實(shí)是創(chuàng)建了一個(gè)fiber并包裝成actor給用戶,每個(gè)actor一被創(chuàng)建就加入調(diào)度器的等待隊(duì)列。<<方法用于向actor傳遞消息,傳遞消息后,該actor也將加入等待隊(duì)列,等待被調(diào)度。

              我們的簡(jiǎn)化版actor庫已經(jīng)寫完了,可以嘗試寫幾個(gè)例子,最簡(jiǎn)單的hello world:
          include FiberActor

          Actor.spawn { puts 
          "hello world!"}
               輸出:
          hello world!

              沒有問題,那么試試傳遞消息:
          actor=Actor.spawn{
             Actor.receive{ 
          |msg|  puts "receive #{msg}"}
          }
          actor 
          << :test_message
              輸出:
          receive test_message
              
              也成了,那么試試兩個(gè)actor互相傳遞消息,乒乓一下下:
          pong=Actor.spawn do
                Actor.receive do 
          |ping|
                  
          #收到ping,返回pong
                  ping << :pong
                end
              end
          ping
          =Actor.spawn do
                
          #ping一下,將ping作為消息傳遞
                pong << Actor.current
                Actor.receive do 
          |msg|
                  
          #接收到pong
                  puts "ping #{msg}"
                end
              end
          #resume調(diào)度器
          Actor.scheduler.reschedule

               輸出:
          ping pong
              
               都沒有問題,這個(gè)超級(jí)簡(jiǎn)單actor基本完成了。可以看到,利用coroutine來實(shí)現(xiàn)actor是完全可行的,事實(shí)上我這里描述的實(shí)現(xiàn)基本上是revactor這個(gè)庫的實(shí)現(xiàn)原理。revactor是一個(gè)ruby的actor庫,它的實(shí)現(xiàn)就是基于Fiber,并且支持消息的模式匹配和thread之間的actor調(diào)度,有興趣地可以去玩下。更進(jìn)一步,其實(shí)采用輕量級(jí)協(xié)程來模擬actor風(fēng)格早就不是新鮮主意,比如在cn-erlounge的第四次會(huì)議上就有兩個(gè)topic是關(guān)于這個(gè),一個(gè)是51.com利用基于ucontext的實(shí)現(xiàn)的類erlang進(jìn)程模型,一個(gè)是許世偉的CERL。可以想見,他們的基本原理跟本文所描述不會(huì)有太大差別,那么面對(duì)的問題也是一樣。

               采用coroutine實(shí)現(xiàn)actor的主要缺點(diǎn)如下:
          1、因?yàn)槭欠菗屨际剑@就要求actor不能有阻塞操作,任何阻塞操作都需要異步化。IO可以使用異步IO,沒有os原生支持的就需要利用線程池,基本上是一個(gè)重復(fù)造輪子的過程。
          2、異常的隔離,某個(gè)actor的異常不能影響到調(diào)度器的運(yùn)轉(zhuǎn),簡(jiǎn)單的try...catch是不夠的。
          3、多核的利用,調(diào)度器只能跑在一個(gè)線程上,無法充分利用多核優(yōu)勢(shì)。
          4、效率因素,在actor數(shù)量劇增的情況下,簡(jiǎn)單的FIFO的調(diào)度策略效率是個(gè)瓶頸,盡管coroutine的切換已經(jīng)非常高效。

              當(dāng)然,上面提到的這些問題并非無法解決,例如可以使用多線程多個(gè)調(diào)度器,類似erlang smp那樣來解決單個(gè)調(diào)度器的問題。但是如調(diào)度效率這樣的問題是很難解決的。相反,erlang的actor實(shí)現(xiàn)就不是通過coroutine,而是自己實(shí)現(xiàn)一套類似os的調(diào)度程序。
              首先明確一點(diǎn),Erlang的process的調(diào)度是搶占式的,而非couroutine的協(xié)作式的。其次,Erlang早期版本是只有一個(gè)調(diào)度器,運(yùn)行在一個(gè)線程上,隨著erts的發(fā)展,現(xiàn)在erlang的調(diào)度器已經(jīng)支持smp,每個(gè)cpu關(guān)聯(lián)一個(gè)調(diào)度器,并且可以明確指定哪個(gè)調(diào)度器綁定到哪個(gè)cpu上。第三,Erlang的調(diào)度也是采用優(yōu)先隊(duì)列+時(shí)間片輪詢的方式,每個(gè)調(diào)度器關(guān)聯(lián)一個(gè)ErtsRunQueueErtsRunQueue內(nèi)部又分為三個(gè)ErtsRunPrioQueue隊(duì)列,分別對(duì)應(yīng)high,max和normal,low的優(yōu)先級(jí),其中normal和low共用一個(gè)隊(duì)列;在Erlang中時(shí)間片是以reduction為單位,你可以將reduction理解成一次函數(shù)調(diào)用,每個(gè)被調(diào)度的process能執(zhí)行的reduction次數(shù)是有限的。調(diào)度器每次都是從max隊(duì)列開始尋找等待調(diào)度的process并執(zhí)行,當(dāng)前調(diào)度的隊(duì)列如果為空或者執(zhí)行的reductions超過限制,那么就降低優(yōu)先級(jí),調(diào)度下一個(gè)隊(duì)列。

             從上面的描述可以看出,Erlang優(yōu)秀的地方不僅在于actor風(fēng)格的輕量級(jí)process,另一個(gè)強(qiáng)悍的地方就是它的類os的調(diào)度器,再加上OTP庫的完美支持,這不是一般方案能山寨的。
              
              
            

          posted @ 2010-04-13 18:31 dennis 閱讀(5645) | 評(píng)論 (1)編輯 收藏

              在小組內(nèi)做的一次分享,基本上是在鋒爺?shù)囊粋€(gè)PPT的基礎(chǔ)上做了一些擴(kuò)充,對(duì)Erlang沒有了解過的朋友可以看看。

          posted @ 2010-04-12 10:45 dennis 閱讀(3480) | 評(píng)論 (0)編輯 收藏

              基本能說明整個(gè)設(shè)計(jì)以及運(yùn)行時(shí)流程,最近搞文檔畫的。

          基本組件結(jié)構(gòu)圖——典型的Reactor+handler模式



          一次IO讀請(qǐng)求的處理過程:





          posted @ 2010-03-26 14:19 dennis 閱讀(2281) | 評(píng)論 (1)編輯 收藏

          媽媽,我不想走
          ——紀(jì)念不幸逝去的孩子們!
          媽媽
          你為什么在哭泣
          今天不是我的生日
          為什么在我身旁點(diǎn)燃紅燭
          沒有歌聲
          也沒有小朋友
          只有你的淚水
          在不停地淌流
          媽媽,拽緊我的手
          我不想走
          媽媽
          你為什么在哭泣
          今天我又惹你生氣
          是我沒完成作業(yè)
          還是我偷偷在玩游戲
          你打我吧
          你罵我吧
          千萬不要把我拋棄
          媽媽,拽緊我的手
          我不想走
          媽媽
          你為什么哭泣
          是老天不公
          還是你的愛沒將我留住
          天堂沒有陽光
          也沒有鳥語花香
          我不去那邊當(dāng)天使
          今生只想做你的心頭肉
          媽媽,拽緊我的手
          我不想走

          來自網(wǎng)易網(wǎng)友評(píng)論,新聞鏈接《福建南平男子在校門口殺害八名小學(xué)生


          posted @ 2010-03-24 09:48 dennis 閱讀(1036) | 評(píng)論 (0)編輯 收藏


          ??? Actor、CoroutineContinuation這三個(gè)概念由于并發(fā)的受關(guān)注而被經(jīng)常提到,這里主要想談下這三者的區(qū)別和聯(lián)系,以便更好的區(qū)分問題領(lǐng)域和討論。首先,Actor和Coroutine在我看來是兩種并發(fā)模型,僅針對(duì)于并發(fā)這個(gè)領(lǐng)域,而Continuation則是程序設(shè)計(jì)領(lǐng)域的一個(gè)概念,相比于Actor和Coroutine是一個(gè)更基礎(chǔ)的概念。

          ??? 那么,什么是Continuation?這個(gè)要從表達(dá)式的求值說起。一個(gè)表達(dá)式的求值可以分為兩個(gè)階段:“What to evaluate?”和“What to do with the value”,“What to do with the value”就是計(jì)算的Continuation。以下面這段代碼為例:
          if?x<3?then
          ???
          return?x+1
          else
          ???
          return?x
          end

          ??? 考察其中的表達(dá)式x<3,這個(gè)表達(dá)式就是“what to evaluate?”,代表你將計(jì)算的東西,然后根據(jù)x<3的結(jié)果決定是執(zhí)行x+1還是直接返回x,這個(gè)根據(jù)x<3的值來決定下一步的過程就是這個(gè)表達(dá)式的Continuation,也就是"what to do with the value"。怎么得到某個(gè)表達(dá)式的Continuation呢?在支持Continuation的語言里提供了call-with-current-continuation的函數(shù),通常簡(jiǎn)稱為call/cc,使用這個(gè)函數(shù)你就可以在任何代碼中得到Continuation。進(jìn)一步,continuation有什么作用呢?它可以做的事情不少,如nonlocal exits、回溯、多任務(wù)的實(shí)現(xiàn)等等。例如在scheme中沒有break語句,就可以用call/cc實(shí)現(xiàn)一些此類高級(jí)的控制結(jié)構(gòu):

          (call/cc?(lambda?(break)
          ????????(
          for-each?(lambda?(x)?(if?(<?x?0)?(break?x)))
          ????????????????
          '(99?88?-77?66?55))
          ????????#t))


          ??? 上面這段代碼查找列表(99 88 -77 66 55)中的負(fù)數(shù),當(dāng)查找到的時(shí)候馬上從迭代中退出并返回該值,其中的break就是一個(gè)continuation。剛才還提到continuation可以實(shí)現(xiàn)回溯,那么就可以實(shí)現(xiàn)一個(gè)窮舉的機(jī)器出來用來搜索解空間,也就是類似Prolog中的回溯機(jī)制,在SICP這本書里就介紹了如何用call/cc實(shí)現(xiàn)一個(gè)簡(jiǎn)單的邏輯語言系統(tǒng)。更著名的就是神奇的amb操作符,有興趣可以看看這里
          ????
          ???? 接下來我們來看看如何continuation實(shí)現(xiàn)多任務(wù),在Continuation的維基百科里給了一段代碼來展示如何用scheme來實(shí)現(xiàn)coroutine,我稍微修改了下并添加了注釋:
          ;;continuation棧,保存了等待執(zhí)行的continuation
          (define?call/cc?call-with-current-continuation)
          (define?*queue*?'())

          (define?(empty-queue?)
          ????????(null??*queue*))

          (define?(enqueue?x)
          ????????(set!?*queue*?(append?*queue*?(list?x))))

          (define?(dequeue)
          ????????(let?((x?(car?*queue*)))
          ??????????????(set!?*queue*?(cdr?*queue*))
          ?????????x))
          ;;啟動(dòng)協(xié)程
          (define?(resume?proc)
          ???????(call/cc
          ?????????(lambda?(k)
          ???????????;;保存當(dāng)前continuation,執(zhí)行proc
          ???????????(enqueue?k)
          ???????????(proc))))
          ;;讓出執(zhí)行權(quán)
          (define?(yield)
          ?????(call/cc
          ??????(lambda?(k)
          ?????????;;保存當(dāng)前continuation,彈出上一次執(zhí)行的cont并執(zhí)行
          ????????(enqueue?k)
          ????????((dequeue)))))
          ;;停止當(dāng)前協(xié)程或者當(dāng)沒有一個(gè)協(xié)程時(shí)停止整個(gè)程序,最簡(jiǎn)單的調(diào)度程序
          (define?(thread-exit)
          ?????(if?(empty-queue?)
          ?????????(exit)
          ?????????((dequeue))))
          (注:scheme以分號(hào)開頭作為注釋)

          ???? 這其實(shí)就是一個(gè)coroutine的簡(jiǎn)單實(shí)現(xiàn),context的保存、任務(wù)的調(diào)度、resume/yield原語……樣樣俱全。使用起來類似這樣,下面這段程序輪流打印字符串:
          (define?(display-str?str)
          ????????(lambda()
          ?????????(let?loop()
          ??????????????(display?str)
          ??????????????(newline)
          ??????????????(yield)
          ??????????????(loop))))

          ;;;創(chuàng)建兩個(gè)協(xié)程并啟動(dòng)調(diào)度器
          (resume?(display-str?"This?is?AAA"))
          (resume?(display-str?"Hello?from?BBB"))
          (thread-exit)

          ???? 任務(wù)非常簡(jiǎn)單,打印下傳入的字符串并換行,然后讓出執(zhí)行權(quán)給另一個(gè)任務(wù)執(zhí)行,因此輸出:
          This?is?AAA
          Hello?from?BBB
          This?is?AAA
          Hello?from?BBB
          This?is?AAA
          Hello?from?BBB
          This?is?AAA
          Hello?from?BBB
          ……

          ??? 談了這么多continuation的應(yīng)用,事實(shí)上我想說明的是continuation可以用來實(shí)現(xiàn)協(xié)程,Ruby 1.9中call/cc和Fiber的實(shí)現(xiàn)(在cont.c)大體是一樣的同樣說明了這一點(diǎn)。

          ???? 接下來我們討論下Actor和Coroutine的關(guān)系,上面提到Actor是一種并發(fā)模型,我更愿意稱之為一種編程風(fēng)格,Actor跟message passing、Duck Typing是一脈相承的。Actor風(fēng)格是可以這么描述:將物理世界抽象成一個(gè)一個(gè)的Actor,Actor之間通過發(fā)送消息相互通信,Actor不關(guān)心消息是否能被接收或者能否投遞到,它只是簡(jiǎn)單地投遞消息給其他actor,然后等待應(yīng)答。Actor相比于Coroutine是一種更高層次的抽象,它提供的receive和pattern match的原語更接近于現(xiàn)實(shí)世界,而使用coroutine編程你還需要手工介入任務(wù)調(diào)度,這在Actor中是由一個(gè)調(diào)度器負(fù)責(zé)的。

          ??? 同樣,Actor可以用coroutine實(shí)現(xiàn),例如Ruby有個(gè)revactor項(xiàng)目,就是利用1.9引入的Fiber實(shí)現(xiàn)actor風(fēng)格的編程,它的實(shí)現(xiàn)非常簡(jiǎn)單,有興趣地可以看看,其實(shí)跟continuation實(shí)現(xiàn)coroutine類似。但是Actor并不是一定要用coroutine才能實(shí)現(xiàn),Actor是一種編程風(fēng)格,你在Java、C#、C++中同樣可以模擬這樣的方式去做并發(fā)編程,.net社區(qū)的老趙實(shí)現(xiàn)過一個(gè)簡(jiǎn)單的ActorScala的Actor實(shí)現(xiàn)是基于外部庫,利用scala強(qiáng)大的元編程能力使得庫的使用像內(nèi)置于語言。

          ??? 總結(jié)下我想表達(dá)的:Continuation是程序設(shè)計(jì)領(lǐng)域的基礎(chǔ)概念,它可以用于實(shí)現(xiàn)coroutine式的多任務(wù),Actor是一種比之coroutine更為抽象的編程風(fēng)格,Actor可以基于Coroutine實(shí)現(xiàn)但并非必須,Actor和Coroutine都是現(xiàn)在比較受關(guān)注的并發(fā)模型。



          posted @ 2010-03-23 11:49 dennis 閱讀(7668) | 評(píng)論 (0)編輯 收藏

          Google正式退出中國,跟朋友的聊天記錄:

          : 真到那天,是中國IT業(yè)的悲哀
          ?某人: 不僅僅是it業(yè)
          ??這是一個(gè)標(biāo)志
          ??鐵幕再次拉開
          ??中國已經(jīng)不在乎外部形象了
          ??也不在乎自己的工程師是否能和世界交流了
          ?只求政權(quán)穩(wěn)定

          ??? 能移民的趕緊吧,不能移民的繼續(xù)被綁架,被代表,被河蟹,喝三鹿,打疫苗,得永生。

          posted @ 2010-03-23 09:25 dennis 閱讀(1041) | 評(píng)論 (2)編輯 收藏

          有興趣地瞧瞧吧,寫的匆忙。

          posted @ 2010-03-20 17:33 dennis 閱讀(3788) | 評(píng)論 (4)編輯 收藏

          僅列出標(biāo)題
          共56頁: First 上一頁 9 10 11 12 13 14 15 16 17 下一頁 Last 
          主站蜘蛛池模板: 赣州市| 临清市| 九台市| 七台河市| 沙雅县| 济宁市| 乐都县| 塘沽区| 百色市| 会东县| 莎车县| 抚顺县| 瓦房店市| 东辽县| 临潭县| 昌江| 渭源县| 昌吉市| 梧州市| 汶上县| 扎兰屯市| 鄂伦春自治旗| 琼结县| 通山县| 扎鲁特旗| 双城市| 毕节市| 旌德县| 彰化县| 闽侯县| 九寨沟县| 铜山县| 鹤庆县| 容城县| 咸丰县| 青神县| 志丹县| 武威市| 原平市| 阿城市| 松阳县|