这个问题或许我发错了板块 , 但从我的理解 , 似乎目前只能发在这个版块 .
问题是这样的 : 
php 源代码 (版本 php v5.6.9 , 根目录使用 PHPSRC 表示 , 假设以线程安全来看(TSRM) ) 中的 :
PHPSRC/ext/session/php_session.h:121 中定义 (session 扩展) :
typedef struct _php_ps_globals {
    char *save_path;
    char *session_name;
    char *id;
    char *extern_referer_chk;
    char *entropy_file;
    ......
} php_ps_globals;
这儿声明了之后需要放到 resource_types_table 中的结构体 php_ps_globals .但是在 
PHPSRC/ext/session/php_session.h:186 中再次使用 typedef
typedef php_ps_globals zend_ps_globals;而后的 192 行
PHPSRC/ext/session/php_session.h:192 (#ifdef ZTS 的前提下)
#define PS(v) TSRMG(ps_globals_id, php_ps_globals *, v)第一个问题是 , 我看这意思 , zend_ps_globals 是个结构体变量 , 是使用 php_ps_globals 定义的 . 因为 192 行的定义和 ZEND_INIT_MODULE_GLOBALS 宏让我这么理解 .---------------------------------------------------以上是第一个问题 , 第二个问题是在 :
PHPSRC/ext/session/session.c:62
PHPAPI ZEND_DECLARE_MODULE_GLOBALS(ps)
使用宏声明了 ts_rsrc_id ps_globals_id; 
但关键问题是 , 期间并无任何调用 
ZEND_INIT_MODULE_GLOBALS 
宏的地方 , MINIT 中没有 , RINIT 中也没有 , 而且,在 MINIT 中 (PHPSRC/ext/session/session.c:2429)
static PHP_MINIT_FUNCTION(session) /* {{{ */
{
    zend_class_entry ce;
    zend_register_auto_global("_SESSION", sizeof("_SESSION")-1, 0, NULL TSRMLS_CC);
    PS(module_number) = module_number; /* if we really need this var we need to init i     t in zts mode as well! */
    ......
}
第三行就开始使用 PS(v) 宏了 , 请问这个结构体的变量 (php_ps_globals) 实体到底在哪声明的?难道 typedef php_ps_globals zend_ps_globals; 用在结构体上 , 就是定义 zend_ps_globals 的变量实体?

解决方案 »

  1.   

    typedef struct _php_ps_globals {
        ......
    } php_ps_globals;
    定义一个结构 _php_ps_globals 并将其命名为 php_ps_globals
    以后在程序里使用 _php_ps_globals 和 php_ps_globals 都是表示该结构typedef php_ps_globals zend_ps_globals;
    这里的意思是:zend_ps_globals 也是先前定义的 _php_ps_globals 结构宏 #define PS(v) TSRMG(ps_globals_id, php_ps_globals *, v)
    的意思是:以后出现 PS(v) = v; 的地方,都替换成
    TSRMG(ps_globals_id, php_ps_globals *, v);
    也就是 v 被分配到 php_ps_globals 结构所需的空间,其他行为由 TSRMG 函数决定
      

  2.   

    版主似乎完全误解了我的意思 .
    ypedef struct _php_ps_globals {
        ......
    } php_ps_globals;
    定义一个结构 _php_ps_globals 并将其命名为 php_ps_globals
    以后在程序里使用 _php_ps_globals 和 php_ps_globals 都是表示该结构
    --------------------------------------------------------------------------------------------------
    其实这种东西 , 别把它当单纯的结构体定义来看 , 在 TSRM 环境下 , 是需要放到 resource_types_table 中的 , 这个 resource_types_table 在各 sapi main 函数初始化时定义 .
    TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename);
    比如 : PHPSRC/sapi/fpm/fpm/fpm_main.c:1614: tsrm_startup(1, 1, 0, NULL); 
    而后续的添加则是通过 ts_allocate_id , 也就是模块中常用的宏 : ZEND_INIT_MODULE_GLOBALS  宏 .在非 ZTS( zend thread safty ) 环境下,这个 "定义全局变量宏" 很好理解:
    #define ZEND_DECLARE_MODULE_GLOBALS(module_name)   \
    zend_##module_name##_globals module_name##_globals;这也就解释了 , 为什么
    PHPSRC/ext/session/php_session.h:186 中再次使用 typedef
    typedef php_ps_globals zend_ps_globals;这两句会存在 , 而且 , 在 PHPSRC/ext/session/session.c:62 使用过 PHPAPI ZEND_DECLARE_MODULE_GLOBALS 宏:
    PHPAPI ZEND_DECLARE_MODULE_GLOBALS(ps)但是全部代码环境 (无论是 MINIT , 或者是 RINT) 却都没有使用过
    ZEND_INIT_MODULE_GLOBALS 
    宏来为 TSRM 环境下 global 变量实例去开辟内存空间 很简单 , 这是 fastcgi 启动的是非线程安全版本 , 对应着非 ZTS , zend##module_name##globals modulename##_globals 已经 ok 了 , 不需要去做 ts_allocate_id 的工作 .我提问的意思其实很简单 , 假设这个代码运行在 PHP 多线程环境下,那为什么我只看到它定义了 ps_globals_id, 却没有看到使用
    ts_allocate_id 去为它分配需要的内存空间 .现在大概也有头绪了 , 该版本只适合运行在 mod_php5 , 或者 cli 或者 cgi 之类的非线程安全环境下面