在PHP初期,是作为单进程的CGI来运行的,所以并没有考虑线程安全问题。我们可以随意的在全局作用域中设置变量并在程序中对他进行修改、访问,内核申请的资源如果没有正确的释放,也会在CGI进程结束后自动地被清理干净。 然后,php被作为apache多进程模式下的一个模块运行,但是这仍然把php局限在一个进程里,我们设置的全局变量,只要在每个请求之前将其正确的初始化,并在每个请求之后正确的清理干净,便不会带来什么麻烦。由于对于一个进程来说,同一个时间只能处理一个请求,所以这是内核中加入了针对每个请求的内存管理功能,来防止服务器资源利用出现错误。 现在,一个进程多个线程的工作方式被越来越多的采用,所以,php内核中亟需一种新的资源管理方式,其最终在php内核中形成了一个新的抽象层:TSRM(Thread Safe Resource Management)。
在一个没有线程的程序中,我们往往倾向于把全局变量声明在源文件的顶部,编辑器会自动的为它分配资源供我们在声明语句之下的程序逻辑中使用。(即使通过fork()出一个子进程,它也会重新申请一段内存,父子进程中的变量从此没有了任何联系) 但是在一个多线程的程序中,如果我们需要每个线程都用有自己独立的资源的话,便需要为每个线程独立开辟出一个区域来存放它们各自的资源,在线程里使用资源的时候,它便会去自己的那一亩三分地里去找,而不会拔了别人的庄稼。
在扩展的Module Init里,扩展可以调用ts_allocate_id()来告诉TRSM自己需要多少资源,TRSM接收后更新系统使用的资源,并得到一个指向刚分配的那份资源的id。
typedef struct {
int sampleint;
char *samplestring;
} php_sample_globals;
int sample_globals_id;
PHP_MINIT_FUNCTION(sample)
{
ts_allocate_id(&sample_globals_id,
sizeof(php_sample_globals),
(ts_allocate_ctor) php_sample_globals_ctor,
(ts_allocate_dtor) php_sample_globals_dtor);
return SUCCESS;
}
未完代续... ...
$Id$