为什么 Ruby 的 IO#pwrite 线程是安全的?

Why is Ruby's IO#pwrite thread-safe?

提问人:Thomas Bromehead 提问时间:2/26/2021 最后编辑:Alter LagosThomas Bromehead 更新时间:3/2/2021 访问量:135

问:

我想知道是否有人可以解释一下为什么 Ruby 的函数在文档中被称为线程安全的:IO::pwrite

这有利于结合 IO#seek 和 IO#write,因为它是 atomic,允许多个线程/进程共享同一个 IO 对象 用于读取不同位置的文件

我对原子性的理解是,要么全有,要么全无,如果引发错误,“事务”将被回滚,因此在这种情况下,文件将以其原始内容关闭(正确吗?
但是,原子性并不能保证线程同步,除非是同步方法?
下面是 pwrite 函数源代码的片段,也可以在此处找到
rb_thread_io_blocking_region

    n = (ssize_t)rb_thread_io_blocking_region(internal_pwrite_func, &arg, fptr->fd);
    if (n < 0) rb_sys_fail_path(fptr->pathv);
    rb_str_tmp_frozen_release(str, tmp);

    return SSIZET2NUM(n);
}
Ruby 多线程 IO

评论


答:

1赞 D. SM 3/2/2021 #1

同步是由内核(操作系统)执行的,而不是由 Ruby 执行的。

根据文档,Ruby 的 pwrite 调用这个 pwrite 来处理同步。

此处描述了 pwrite 系统调用的行为。具体说来:

在对常规文件的 write() 成功返回后:

  • 从文件中的每个字节位置成功读取() 修改后的写入将返回 write() 替换为该位置,直到该字节位置再次出现 改 性。

  • 任何后续成功写入 () 到相同字节位置的 file 将覆盖该文件数据。

广泛的基本原理更详细地讨论了序列化。