MRI Ruby多线程期间内存访问特性

4
在一些高级编程环境中(如Java、.NET),当从多个线程访问同一内存时,你必须明确地标记它为volatile或synchronized,否则你可能会因为CPU的乱序执行或其他优化而获得来自某些缓存的旧值或乱序值。
在MRI Ruby中,有一段时间使用本机操作系统线程。每个线程有时会执行Ruby代码(我假设是这样,但不确定),即使由于VM锁定而永远不会真正并行。
我猜MRI以某种方式解决了这些旧值/乱序值问题,因为Ruby语言中没有volatile结构,而我从未听说过旧值问题。
Ruby语言或MRI特别针对多个线程的内存访问提供了哪些保证?如果有人能指点我相关文档,我将非常感激。谢谢!
1个回答

1
听起来你的具体问题是,当切换线程时,Ruby是否会隐式地提供内存屏障,以便在处理器级别发生的所有缓存/重新排序问题都会自动解决。
我认为MRI确实提供了这个功能,否则GVL就没有意义;如果即使在这种情况下它们最终仍然可能读取/写入过期数据,为什么要限制一个线程运行?很难找到提供此功能的精确位置,但我认为入口点是通过RB_VM_LOCK_ENTER,它被整个代码库调用,最终调用vm_lock_enter。这里的代码强烈暗示着存在内存屏障:
        // lock
        rb_native_mutex_lock(&vm->ractor.sync.lock);
        VM_ASSERT(vm->ractor.sync.lock_owner == NULL);
        vm->ractor.sync.lock_owner = cr;

        if (!no_barrier) {
            // barrier
            while (vm->ractor.sync.barrier_waiting) {
                unsigned int barrier_cnt = vm->ractor.sync.barrier_cnt;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接