• 2007-02-08

    锁住数据

    这几天在写多线程程序。

    有了一定的开发经验之后,写程序主要是查找API用法的过程。对于多线程来说,主要就是线程创建、同步互斥这些基本API的用法。互斥主要是用锁,我查了一下用Mutex做锁的方法,基本上是看一下用法就知道怎么用了。不过,写代码的时候,突然发现一个很别扭的地方,我不知道自己的锁该锁在哪里了。想来想去,原来是我找到那几篇教程的误导。

    通常多线程教程中,给人的例子会给出一个线程的函数,然后在其中给出锁的用法,比如:
    void threadFunc(void* param) {
        lock(&my_lock);
        ...
        unlock(&my_lock);
    }

    这段代码给人传递的信息是用锁来锁住这段代码,而事实上,锁的真正目标并非代码,而是数据。

    想想那些来自操作系统课程的例子,比如取钱的例子。甭管怎么取,总之,银行不愿意亏,所以,它要保护的是你的账户。至于你究竟是通过ATM取款还是网上银行,它根本不关心。由此可见,锁的目标是内容,而非行为。

    当然,锁住数据之后,一般会有一系列的操作,所以,这越发像保护代码了。但事实上,不是。在这点上,Java做得比较不错,它把锁绑在了对象上,也就是相当于跟到了数据上,synchronized的时候,锁住的就是数据。

    在程序设计中,代码只是用不同的方式在处理数据,最为核心的还是数据。所以,别管戏法如何变,盯住数据,我们就可以在暴风骤雨中岿然不动了。

    又一次谈到了数据,之前是《管窥OS——进程透明化》和《有状态的程序》。

  • 2007-02-02

    体验YARV

    YARV,Yet Another Ruby VM,又一个Ruby VM。

    其实,我觉得它的名字算不上准确,因为原来Ruby算不上拥有VM。当然,按照作者的本意,这个名字不会长久的存在下去,因为项目如果成功,它就会成为Ruby的一部分,不成功的话,没人会记住它。事实上,它正一步步走向成功,因为现在它已经被合并到Ruby的主干代码中。

    我不想苦苦等待YARV随着发行版来到我们身边,于是我选择提前体验YARV。到Ruby的网站上,下载Nightly Snaphot版本,我们就可以拥有最新的Ruby版本,当然,这样做的代价是这个版本可能不如正式的发布版那样稳定。事实上,我自己在编译的时候就遇到了一些小问题,幸好,简单修改一下便万事大吉。

    关于如何编译Ruby,我已经在之前的blog上讨论过,这里就不再赘述。

    下面是我用来体会YARV的一段代码:
    def fibonacci(n)
        if n == 1 or n == 0
            n
        else
            fibonacci(n - 1) + fibonacci(n - 2)
        end
    end

    start_time = Time.new.to_f
    puts start_time
    puts fibonacci(30)
    end_time = Time.now.to_f
    puts start_time
    puts end_time - start_time

    首先,我用Ruby 1.8.5-p12运行这个版本,我最关心的运行时间大概是:
    2.60199999809265

    同样一段代码用加入YARV的Ruby来跑:
    0.401999950408936

    大幅度提高,看来YARV果然不负众望。如果希望继续体会YARV,现在Ruby的代码中还多了一个benchmark目录,里面全是一些耗时的运算。

    既然YARV号称虚拟机,自然要有自己的指令集。JRuby正在开发的代码之中,已经开始提供对YARV指令的支持,Ola Bini在自己的blog上写过几篇与之相关的blog:
    Executing YARV (in JRuby)
    YARV tail call optimization in JRuby