编程语言
首页 > 编程语言> > PHP内部原理:TSRMLS_FETCH如何工作?

PHP内部原理:TSRMLS_FETCH如何工作?

作者:互联网

PHP Internals TSRMLS_FETCH宏如何工作?

PHP Manual

While developing extensions, build errors that contain “tsrm_ls is undefined” or errors to that effect stem from the fact that TSRMLS is undefined in the current scope, to fix this, declare the function to accept TSRMLS with the appropriate macro, if the prototype of the function in question cannot be changed, you must call TSRMLS_FETCH within the function body.

我了解使用适当的宏声明函数以接受TSRMLS意味着使用TSRMLS_C, TSRMLS_D, TSRMLS_CC, and TSRMLS_DC定义带有额外参数/参数的调用函数.

但是,如果所讨论函数的原型无法更改,则必须在函数体内调用TSRMLS_FETCH会使我有些困惑.如果我查看php-src herehere,则TSRMLS_FETCH似乎是一个空宏.

这样就给我留下了一个问题-TSRMLS_FETCH甚至如何工作?在编译时是否还有其他东西填充此宏?

解决方法:

首先,我不会过多地关注手册在PHP内部的内容.它已经过时了,很有可能在不久的将来将其从手册中删除.当前有两个网站专门介绍PHP的内部原理:PHPInternalsBook.comPHPInternals.net(我为后者编写内容).还有几个不错的博客,包括Nikita’sJulien’s.

PHP的5.x系列中的TSRM具有很高的侵入性.如果要从函数内部访问任何Zend globals,则可以选择从函数调用中获取TLS内存指针(例如pthread_getspecific,这相对昂贵),或者通过函数参数传播TLS内存指针(凌乱且错误-容易发生外遇,但方法更快).您提到的TSRMLS_FETCH宏用于前一种方法.

在PHP 7.x中,已完全删除了传播TLS内存指针(通过TSRMLS_ [D | C] C?宏)(尽管仍为向后兼容而定义了它们的宏-它们只是不做任何事情).现在,访问TSRM TLS的首选方法是通过其静态缓存.这基本上只是用于保存当前TLS内存指针的线程局部全局变量.

以下是相关的宏:

#define TSRMLS_CACHE _tsrm_ls_cache // the TLS global variable
#define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE = NULL; // define it
#define TSRMLS_CACHE_UPDATE() TSRMLS_CACHE = tsrm_get_ls_cache() // update it - i.e. calls pthread_getspecific()
#define TSRMLS_CACHE_RESET()  TSRMLS_CACHE = NULL // reset it

使用上面的宏确实需要特别注意以适当地更新静态缓存(通常在扩展的GINIT(有时是RINIT)阶段).但是,这是一种更干净的方法,可提供对TLS内存指针的访问,而不会通过函数参数传播它,也不会始终获取它(通过pthread_getspecific和类似的东西)会降低性能.

额外阅读:

> Native TLS(在PHP 7.0中引入此更改的RFC)
> Threads and PHP(Julien在TSRM上的博客文章)

标签:php-internals,macros,c-3,php
来源: https://codeday.me/bug/20191025/1927320.html