【问题标题】:Why are static variables in an xsub not thread safe?为什么 xsub 中的静态变量不是线程安全的?
【发布时间】:2018-11-13 18:45:46
【问题描述】:

根据perldoc threads

从 Perl 5.8 开始,线程编程已经可以使用模型 称为解释器线程,它提供了一个新的 Perl 解释器 每个线程,默认情况下,不会产生任何数据或状态信息 在线程之间共享。

以上引用中提到的datastate 信息类型是什么?根据perldoc perlxs

从 Perl 5.8 开始,定义了一个宏框架以允许 静态数据安全地存储在将被访问的 XS 模块中 来自多线程 Perl。

所以在我看来静态变量是在线程之间共享的?但是 Perl 变量不是共享的吗? (我想弄清楚到底什么样的数据是线程安全的,以及如何创建线程安全的模块)

【问题讨论】:

  • 我认为 Perl 级别的变量(任何具有 SV 或来自 newSV 的变量)都不会共享,而 C/XS 级别的任何变量都是共享的,因为 C 就是这样。

标签: multithreading perl xs


【解决方案1】:

每个线程都有自己的解释器。此结构[1] 存储构成perl 的所有内容,包括解析器状态、正则表达式引擎状态、符号表和所有“SV”(包括标量、数组、哈希、代码、 ETC)。从 Perl 副本中创建新线程会复制当前解释器。

XS 代码可以安全地使用 Perl API,因为每个函数都有一个参数来指定要使用的解释器。由于宏,这通常对代码不可见,但您可能已经注意到对“THX”或“Perl 上下文”的引用。只是不要将属于一个解释器的 SV 传递给另一个解释器。 (您可能听说过由此导致的“Free to wrong pool”错误消息。)

但是 Perl 不能为超出其知识或控制范围的事物提供任何保护,例如它加载的外部库的静态存储。没有制作这些副本。两个线程可能同时调用同一个 C 函数,因此需要像编写多线程 C 程序一样采取预防措施。

您引用的那个宏框架允许访问每个解释器的存储。它还允许库指定一个函数以在创建新 Perl 线程时调用以将变量克隆到新解释器中。


  1. 如果 Perl 是在没有 -Dusemultiplicity 的情况下构建的,则 Perl 解释器由一个 bajillion 全局(静态)变量组成。 MULTIPLICITY 将它们移动到一个结构中,并为 Perl API 调用添加一个上下文参数。这会降低性能,但它允许一个进程拥有多个 Perl 解释器。因为 Perl 的线程构建需要这个,所以构建线程 perl (-Dusethreads) 假定 -Dusemultiplicity

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-05
    • 2018-08-25
    相关资源
    最近更新 更多