天天看點

Ruby Fiber指南(二)參數傳遞

    這一篇其實也算是fiber程式設計的基礎篇,隻不過參數傳遞算是一個比較重要的主題,是以獨立一節。參數傳遞發生在兩個fiber之間,作為fiber之間通訊的一個主要手段。

    首先,我們可以通過resume調用給fiber的block傳遞參數:

1 #resume傳遞參數給fiber

2 f=fiber.new do |a,b,c|

3    p a,b,c

4 end

6 f.resume(1,2,3)

這個例子展示了怎麼向fiber的block傳遞參數,f這個fiber簡單地将傳入的參數列印出來并終止。

    其次,fiber#yield也可以傳遞參數給調用resume作為傳回結果,猜猜下面的代碼列印什麼?

1 #yield傳遞參數給resume

2 f=fiber.new do |a,b|

3   fiber.yield a+b,a-b

    p a,b

6 p f.resume(10,10)

7 p f.resume(3,4)

正确的答案是:

[20, 0]

10

[10, 10]

讓我們分析下代碼的執行過程:

1、第6行第一次調用resume,傳入10,10兩個參數

2、f開始執行任務,它的任務是調用fiber#yield,并将參數相加和相減的結果作為參數給yield,也就是執行fiber.yield 20,10

3、f調用yield之後挂起,傳回root fiber,yield的兩個參數10、20作為傳回結果列印。

4、第7行代碼,root fiber再次調用resume并傳入參數,f被切入并執行代碼p a,b,列印a、b,a和b仍然是上次調用儲存的10,而非resume傳入的3和4。

5、f執行完畢,傳回p a,b的結果作為resume結果,也就是[10,10]

    剛才看到上面yield向resume傳遞參數的例子中第二次調用resume的參數3和4被忽略了,事實上如果還存在一次yield調用,那麼3和4将被作為yield的傳回結果使用,這就是我們接下來将看到的,通過resume調用傳遞參數作為fiber中yield的傳回結果:

1 #resume傳遞參數給yield

2 f=fiber.new do

3    1 + fiber.yield

6 p f.resume(1)

7 p f.resume(2)

這次的列印結果将是:

nil

3

   第一次調用resume傳入的1将被忽略,因為f的block不需要參數,然後f執行1 + fiber.yield,在yield的挂起,加法運算沒有繼續,因為yield的調用沒有參數,是以第一次resume傳回nil;第二次resume調用傳入2,這時候2将作為fiber#yield的調用結果跟1相加,完成加法運算,得到的結果就是3,這個結果作為fiber的傳回值傳回給調用者。

    總結下上面我們談到的四種傳遞參數的情形:通過resume向fiber的block傳遞參數、通過yield向調用者傳遞參數、通過resume向yield傳遞參數、fiber傳回值傳遞給調用者。

    文章轉自莊周夢蝶  ,原文釋出時間2010-03-11