• 哥们,果然你很活跃呀😀

  • 你这个代码的线程调度是不会影响 @a@c的值得, 可以用这个代码来验证

    @a = 1
    r = []
    10.times do |e|
    
    Thread.new {
       @c = 1
       @c += @a
       r << [e, @c]
    }
    end
    

    r 里面的值, 虽然e的前后顺序不一样, 但是, @c的值是一致的

    但是你在@c=1@c += @a中间加一个puts的话, 这个就会触发gil的lock, 数据异常了

    @a = 1
    r = []
    10.times do |e|
    
    Thread.new {
       @c = 1
       puts 1
       @c += @a
       r << [e, @c]
    }
    end
    
  • 你这个答案是靠谱的, 其实题主最后一个代码是不存在线程安全问题的

    GIL的工作机制不像大家想象的一样, 在ruby代码的任何一个点都会切换到另外一个线程去工作

    而是有几个明确的工作点的

    • 方法的调用和方法的返回, 在这两个地方都会检查一下当前线程的gil的锁是否超时,是否要调度到另外线程去工作
    • 所有io相关的操作, 也会释放gil的锁让其它线程来工作
    • 在c扩展的代码中手动释放gil的锁
    • 还有一个比较难理解, 就是ruby stack 进入 c stack的时候也会触发gil的检测
    static void
    gvl_acquire_common(rb_vm_t *vm)
    {
        if (vm->gvl.acquired) {
    
        vm->gvl.waiting++;
        if (vm->gvl.waiting == 1) {
            /*
             * Wake up timer thread iff timer thread is slept.
             * When timer thread is polling mode, we don't want to
             * make confusing timer thread interval time.
             */
            rb_thread_wakeup_timer_thread_low();
        }
    
        while (vm->gvl.acquired) {
            native_cond_wait(&vm->gvl.cond, &vm->gvl.lock);
        }
    
        vm->gvl.waiting--;
    
        if (vm->gvl.need_yield) {
            vm->gvl.need_yield = 0;
            native_cond_signal(&vm->gvl.switch_cond);
        }
        }
    
        vm->gvl.acquired = 1;
    }
    
    static void
    gvl_acquire(rb_vm_t *vm, rb_thread_t *th)
    {
        native_mutex_lock(&vm->gvl.lock);
        gvl_acquire_common(vm);
        native_mutex_unlock(&vm->gvl.lock);
    }
    
    static void
    gvl_release_common(rb_vm_t *vm)
    {
        vm->gvl.acquired = 0;
        if (vm->gvl.waiting > 0)
        native_cond_signal(&vm->gvl.cond);
    }
    
    static void
    gvl_release(rb_vm_t *vm)
    {
        native_mutex_lock(&vm->gvl.lock);
        gvl_release_common(vm);
        native_mutex_unlock(&vm->gvl.lock);
    }
    

    这几个方法是用来控制gil的锁的, 可以参考一下gil在c里面的调用情况

  • 有兴趣的话答个题我们来聊聊

  • 额, 这个重点从来不是你答的什么,而是从你答得什么中我们聊出来的那些😀

  • 根据您的面试题的代码,我们才可以更好展开了解您的技能域 也让面试不变的太清谈么

    😄

  • #29楼 @adam_chen 手机型号是啥, android版本是啥?

  • 30 分钟搭建私有 Gems 源 at 2016年08月22日

    #11楼 @sevk 只是跑server的ruby必须是ruby .2.2, 在ruby 2.3的项目中, 用这个gem server 尚未碰到问题

  • 30 分钟搭建私有 Gems 源 at 2016年08月16日

    可以试试 gemstash 是bundler官方推荐的

  • 如果只是为了解决 assets precompile的话...干净整洁,也不用编译这么大的一个V8