multithreading - 为什么 xsub 中的静态变量不是线程安全的?
问题描述
从 Perl 5.8 开始,线程编程可以使用一种称为解释器线程的模型,它为每个线程提供一个新的 Perl 解释器,并且默认情况下,线程之间不会共享任何数据或状态信息。
上述引用中提到了哪些类型data
或信息?state
根据perldoc perlxs
:
从 Perl 5.8 开始,定义了一个宏框架以允许静态数据安全地存储在 XS 模块中,这些模块将从多线程 Perl 访问。
所以在我看来静态变量是线程之间共享的?但是 Perl 变量不是共享的吗?(我试图弄清楚什么样的数据是线程安全的,以及如何创建线程安全模块)
解决方案
每个线程都有自己的解释器。这个结构[1]存储构成 的所有内容perl
,包括解析器状态、正则表达式引擎状态、符号表和所有“ SV
”(包括标量、数组、哈希、代码等)。从 Perl 副本中创建一个新线程会生成当前解释器的副本。
XS 代码可以安全地使用 Perl API,因为每个函数都有一个参数来指定要使用的解释器。由于宏,这通常对代码是不可见的,但您可能已经注意到对“ THX
”或“Perl 上下文”的引用。只是不要将属于一个解释器的 SV 传递给另一个解释器。(您可能听说过由此导致的“Free to wrong pool”错误消息。)
但是 Perl 无法对超出其知识或控制范围的事物提供任何保护,例如它加载的外部库的静态存储。没有制作这些副本。两个线程可以同时调用同一个 C 函数,因此需要像编写多线程 C 程序一样采取预防措施。
您引用的那个宏框架可以访问每个解释器的存储。它还允许库指定一个函数来调用创建新 Perl 线程以将变量克隆到新解释器中。
- 如果 Perl 是在没有 的情况下构建
-Dusemultiplicity
的,则 Perl 解释器由一个 bajillion 全局(静态)变量组成。MULTIPLICITY
将它们移动到一个结构中并向 Perl API 调用添加一个上下文参数。这会降低性能,但它允许一个进程拥有多个 Perl 解释器。因为 Perl 的线程化构建需要这个,所以构建一个 threadedperl
(-Dusethreads
) 假定-Dusemultiplicity
.
推荐阅读
- makefile - 在变量名中使用 % 模式
- reactjs - 更改文件夹后反应找不到图像
- node.js - 如何使用 nodejs 和 okta 进行应用程序注销
- javascript - 如何使 Firefox 的画布与基于 Chromium 的浏览器中的行为相同?
- javascript - 如何在没有严格模式的情况下运行特定测试或所有内容
- javascript - 如何使用 Firebase 模拟器从单元测试中调用 firebase 函数?
- javascript - Does jQuery selector iterates through all elements?
- c++ - 在 C++ 中,是否有一种编译时方法来检查函数是否具有特定的覆盖?喜欢运算符<
我有一个模板类,我想根据是否
operator<<()
为它专门用于的类型定义了一个版本来改变它的行为。例如,struct HasStreamOp { int i, j; friend ostream & operator<<( ostream &
- laravel - 存储在数据库中时使用方法类型时的 Laravel 错误
- c - 使用 AVL 树在笛卡尔平面上优化搜索的方法