[email protected]:~$

  • Celluloid中的任务中断和Condition

    ######Celluloid有个很神奇的机制(<–示例代码) Celluloid每次任务(方法调用)会用Fiber去包装 当一个FiberTask因为某些代码被中断时,此时Celluloid可以回到线程执行任务的方法 相当于中断的任务已经结束 之后Actor线程继续的从mailbox取任务 ######某些代码! FiberTask会因某些方法被中断,上面的示例代码中中断当前Fiber的是sleep方法,这个方法由Celluloid做了覆盖 sleeper = Sleeper.new(@timers, interval) Celluloid.suspend(:sleeping, sleeper) Celluloid.suspend这行代码就起到中断作用,(知道它会中断当前Fiber即可,实际会根据后边的参数调用一些callback) ######中断了。。如何恢复? def before_suspend(task) @timers.after(@interval) { task.resume } end 这就是参数sleeper的callback,可以看到利用定时器来执行恢复的task 如果Fiber.resume的时候当前正在执行别的FiberTask会怎么办?岂不是会乱掉? after定时器也是通过FiberTask来执行的,所以到时间后我们的block会被传到mailbox中,就像一个新任务被调用一样,完全没有问题! ######某些方法能中断? actor当然不是再任何情况下都可以自己中断..上文sleep方法是之一,另外Celluloid还提供了Condition类来进行中断 Condition类和ConditionVariable行为类似 ######Condition ConditionVariable主要是用来在线程间统一资源的,README很详细 在Celluloid中应该用Celluloid::Condition来完成这件事,他们的行为是差不多的 Celluloid::Condition的好处是会中断当前的FiberTask, 这样Actor可以去执行之后的Task,而不是一直block住,基本原理和之前sleep是差不多的 Condition可以很好用的去做些同步操作,而且不会浪费线程

  • ruby-stdlib-delegate

    一直对delegate效率抱有疑问(虽然从未做过牛X到需要改进这里效率的项目..) SimpleDelegate使用的果然是method_missing方法 method_missing据说是很慢的。。因为ruby要查询很多层方法 ActiveRecord采用的改进方案是method_missing中去创建方法,这样第二次调用就会命中创建的方法了 不过不到框架的级别应该是不需要在意这些的.. DelegateClass方法会返回一个匿名类,并且作为参数的类的实例方法都会在其中定义一遍 所以没有method_missing,当然用起来不是那么Simple.. delegate库解决了像是equal?, methods, instance_methods等等很多类似的小问题

  • Celluloid中的Atom Mode与锁

    Celluloid默认是Atom Mode执行的, 这种模式下可以中断当前执行的任务 先执行下一个 Celluloid提供了一个sleep方法,在Actor内部调用sleep时会中断当前Fiber并且用timer异步来恢复 def before_suspend(task) @timers.after(@interval) { task.resume } end 当中断当前的TaskFiber时,Actor即可处理下一个message,被中断的message等待timer去恢复自身 def task(task_type, method_name = nil, &block) if... .... else @task_class.new(task_type, &block).resume#中断fiber时从此处返回 end end 我们在Actor上的每次调用都是一个独立Fiber Actor 线程是一个worker,来运行多个Fiber,个人感觉这里有点矛盾,Celluloid把多线程程序,变成了多Fiber程序,不同的Fiber很有可能并发访问同一个变量 而exclusive就是Celluloid中的Fiber的锁。actor本身就是消除锁的,而现在却又引入了一个新的锁。 不过实际写过Celluloid程序后,感觉还是不要对这个锁太担心的,实际中只有中断时(调用sleep)才会插入新的fiber,而我们在写需要同步执行的代码时 一般的正常人类是不会在其中插入个sleep的,如果必须确定代码的同步 则要把代码写在exclusive块中(一般不需要,exclusive作用是阻止在本块中Fiber的中断) 这种机制虽然带来了少许的复杂性但是 绝大多数情况下我们无需知道这种机制也可正常的运作程序 即使用到exclusive, 也只是很简单的应用 可以更加有效率的利用线程 Celluloid把任务和worker之间隔离开,之后可能会把thread和actor也进行抽象分离,这样增加了灵活性和效率, 不过随之也带来了复杂性, 其中得失还是很难说清的