原本作了一個併發抓取,覺得Ruby1.9之後添加的Fiber是相似於golang那種,能夠實現併發運行,但是發現效率沒有提升,爲了確認Fiber是否是在併發執行,因而我作了一個這樣的測試代碼。php
首先搞一個php文件:node
<?php $i = intval(isset($_GET['i']) ? $_GET['i'] : (!empty($argv[1]) ? $argv[1] : 0)); if($i>0){ sleep(5-$i); } echo $i, "\n";
而後用命令行測試,確認這個php文件是不會block的(由於沒有session鎖,應該不會block)golang
time for i in {1..5}; do (curl localhost/test.php?i=$i) & if [ "$i" -eq "5" ]; then wait; fi ; done time for i in {1..5}; do (php test.php $i) & if [ "$i" -eq "5" ]; then wait; fi ; done
這裏兩種方式運行時間都是4秒左右,證實,是能夠並行運行。 real 0m4.019s
而後用fiber執行: real 0m10.086s 10秒左右,證實這徹底是一個一個在跑的。
shell
#!/usr/bin/env ruby require 'open-uri'; fib = Fiber.new do (1..5).each do |i| Fiber.yield open("http://localhost/test.php?i=#{i}").read end end Fiber.new do 5.times do puts fib.resume end end.resume
結果測試發現根本不能實現併發,並且是一個一個在跑,跑完一個跑下一個,因此別在被誤解了Fiber根本不能併發執行,並且還有一個更奇葩的,若是是5個Fiber.yield,在resume的時候卻能夠調用6次resume,這個設計真不怎麼樣。
後來我在 stackoverflow上找到這個 http://stackoverflow.com/questions/3066392/can-ruby-fibers-be-concurrent
看第二個回答,大概是說,Fiber只是一種 control-flow 結構,並非用來搞併發的,他們不能併發運行,只能算是一種 Coroutine ,和並行執行不是一種東西,在ruby裏,惟一能實現併發的是 Thread,那麼我就奇怪爲什麼網上有那麼多人宣稱能夠用 Fiber 來實現併發運行?併發和協程但是不同的。編程
不過也能夠這樣來講,Fiber是能夠實現 concurrency,這個 concurrency 並非 Parallelism,就是說,能夠實現所謂的併發,可是內部倒是一個一個運行的,並且並不會由於IO阻塞的時候自動調度,你須要手動調度,實際性能沒有任何提高,用了只會增長代碼邏輯複雜度,絲絕不能帶來任何益處,一樣是concurrency,golang、nodejs均可以在IO阻塞時候自動調度,因此能實現正真意義上的併發編程,但Fiber,只不過是把任務一個一個壓棧,而後在一個一個等待着他們運行完畢,徹底不能自由調度,真沒見到有什麼實質用處。ruby
好比 這裏 http://www.infoq.com/cn/news/2007/09/ruby-1-9-fibers
標題就是 :Ruby 1.9加入纖程實現輕量級併發 ,直接就是在誤導新手啊.session