Ruby的Fiber根本不是用来做并发的~

本来做了一个并发抓取,以为Ruby1.9以后添加的Fiber是类似于golang那种,可以实现并发运行,可是发现效率没有提高,为了确认Fiber是不是在并发执行,于是我做了一个这样的测试代码。

首先搞一个php文件:

<?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)

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秒左右,证明这完全是一个一个在跑的。

#!/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,只不过是把任务一个一个压栈,然后在一个一个等待着他们运行完毕,完全不能自由调度,真没见到有什么实质用处。

比如 这里 http://www.infoq.com/cn/news/2007/09/ruby-1-9-fibers   
标题就是 :Ruby 1.9加入纤程实现轻量级并发 ,直接就是在误导新手啊.

时间: 2024-08-11 13:11:38

Ruby的Fiber根本不是用来做并发的~的相关文章

ruby语言是什么东西

1.简介    Ruby是日本的Yukihiro Matsumoto写的,简单易学的面向对象的脚本语言,像perl一样,有丰富的文字处理.系统管理等丰富 功能,但是ruby要简单,容易理解和扩充.跟python很类似,但是在国内远没有python有名. Ruby是一种功能强大的面向对象的脚本语言,可以使用它方便快捷地进行面向对象程序设计.与Perl类似,而且Ruby具有强大的文本处理功能,使文本处理变得简单.此外还可以方便地使用C语言来扩展Ruby的功能.若您曾经“想要一种简单的面向对象的语言”

Ruby 连接MySQL数据库

使用Ruby连接数据库的过程还真的是坎坷,于是写点文字记录一下. 简介 Ruby简介 RubyGems简介 包管理之道 比较著名的包管理举例 细说gem 常用的命令 准备 驱动下载 dbi mysql mysql2 MySQL的CC连接器 测试环境 代码测试 连接数据库 CRUD Select Delete Update Insert 仿PreparedStatement 假冒伪劣版 假冒伪劣进阶版 处理结果集 表结构 结果集遍历 总结 简介 Ruby简介 Ruby是一种纯粹的面向对象编程语言.

有赞分层自动化测试实践

1. 背景 先理一下自动化测试的概念,从广义上来说,一切通过工具(程序)的方式来代替或者辅助手工测试的行为都可以成为自动化.从狭义上来说,通过编写脚本的方式,模拟手工测试的过程,从而替代人工对系统的功能进行验证. 有赞是一家互联网行业的创业公司,测试起步较晚,发布非常频繁,就算每次只回归核心功能,对人数极少的几个测试人员来说工作量巨大,且基本是重复劳动,极其枯燥,持续时间长了也容易出错. 所以初期我们测试自动化切入的思路非常简单:从实际用户的角度出发,模拟真实的操作,替代现有的手工测试用例的执行

JSPatch实现原理详解

本文转载至 http://blog.cnbang.net/tech/2808/ JSPatch以小巧的体积做到了让JS调用/替换任意OC方法,让iOS APP具备热更新的能力,在实现 JSPatch 过程中遇到过很多困难也踩过很多坑,有些还是挺值得分享的.本篇文章从基础原理.方法调用和方法替换三块内容介绍整个 JSPatch 的实现原理,并把实现过程中的想法和碰到的坑也尽可能记录下来. 基础原理 能做到通过JS调用和改写OC方法最根本的原因是 Objective-C 是动态语言,OC上所有方法的

SOA系统架构

一.SOA原理与应用 1.SOA原理 SOA(Service-oriented architecture,面向服务架构). SOA的价值在于跨越了不同应用系统.不同技术的整合,这种整合改变现有的商业模型. SOA是在计算环境下设计.开发.应用.管理分散的逻辑(服务)单元的一种规范.这个定义决定了SOA的广泛性.SOA要求开发者从服务集成的角度来设计应用软件,即使这么做的利益不会马上显现.SOA要求开发者超越应用软件来思考,并考虑复用现有的服务,或者检查如何让服务被重复利用.SOA鼓励使用可替代的

一步一步学会puppet(三)--节点和模板

这篇主要介绍puppet中需要理解的2个重要概念:节点和模板: =================================================================== 1 节点 1.1 定义 1.2 详细说明 1.3 实例 2 模板 2.1 定义 2.2 详细说明 2.3 模板文件的语法 2.4 模板文件实例 2.5 使用模板文件生成实际配置文件 ===========================================================

高手问答精选:Go 语言 —— 云计算时代的 C 语言(类似于一个FAQ)

Go 语言被称为云计算时代的 C 语言,它在软件开发效率和运行效率之间做出了绝佳的权衡.这使得它既适应于互联网应用的极速开发,又能在高并发.高性能的开发场景中如鱼得水.正因如此,许多互联网公司,尤其是云计算领域的创业公司都选择 Go 语言作为其技术栈的重要组成部分.因此,对于广大的开发者而言,关注和学习 Go 语言就十分有必要了. 在高手问答第 149 期中,我们围绕 Go 进行了提问,并邀请了 @hyper0x(郝林)作为高手嘉宾. 本文整理了此次高手问答中一些精彩的问答. Go 语言使用场景

单点登录方案的比較和选择

1.OpenSSO 以前Sun的一款开源产品,从非常少的那一点点中文资料上来看,这个能实现我须要的那种SSO模式. 从SUN被Oracle收购之后,Oracle便关闭了OpenSSO这个项目,如今在网上下不到OpenSSO的安装文件.并且以前的那些在SUN公布的非常多相关的帮助文档,大多数链接都失效了,全都指向了Oracle的同一个页面,找不到文档中相应的安装文件. 2.OpenAM OpenAM的原型应该就是OpenSSO,据说是在Oracle关闭OpenSSO时,被"挽救"下来的.

如何在Java平台上使用脚本语言做Java开发

如何在Java平台上使用脚本语言做Java开发     最近开始流行区分Java平台和Java语言,但很多Java开发者还是不能确定如何在 Java应用程序开发中结合脚本.本篇文章,Gregor Roth给出了在Java平台上使用脚本的方法.通过这篇文章,你可以了解怎样在你的Java应用程序中使用脚本,是否你要通过使用Groovy和 Jython把不同的Java应用程序模块粘合在一起,或者写一个你自己的基于JRuby的应用程序,适用于Java平台. 作为一个Java开发者,你可能已经注意到了,J