从了解CGI来为PHP选择线程安全和非线程安全

Windows版的PHP从版本5.2.1开始有Thread Safe(线程安全)和None Thread Safe(NTS,非线程安全)之分,为何会有这样的划分?区别是什么?该如何选择?刚接触难免会有这样的疑问,我试着去理解一下并和大家分享。

None-Thread Safe就是非线程安全,在执行时不进行线程(thread)安全检查;Thread Safe就是线程安全,执行时会进行线程(thread)安全检查,以防止有新要求就启动新线程的 CGI 执行方式耗尽系统资源。

PHP程序是用来解释php代码提供Web服务的,它本身是运行在操作系统之上的一个程序,为了将网页和操作系统的工作联系起来,引入了CGI(Common Gateway Interface,通用网关接口)的概念,它是WWW服务器主机对外服务的标准接口,将网页文件上的交互转化为操作系统的程序来运行。

CGI是一类接口,定义了网页动作、数据与服务器主机程序的交互,将网页变成了程序的一部分,也为网页赋予了程序的灵性。CGI也是实现了该接口的一个可执行程序,在Unix系统下一般放在cgi-bin子目录下,在windows环境下根据服务器的不同略有不同,一般放在cgi-win目录下。如果访问https://mail.qq.com/cgi-bin/loginpage这样的路径,即执行了CGI程序。提交Form表单的操作同样是执行CGI程序来完成数据处理工作的。

CGI的工作流程是:用户请求激活了CGI-->CGI将用户提交的数据或请求进行解析-->提交个服务器主机进行处理(如数据库查询)-->将服务器处理结果通过网页文件返回-->CGI结束。

CGI的工作方式可笼统地分为单进程和多进程两种。多线程方式下,在接受到每一个用户请求即产生一个进程进行处理,优点是对于每一个用户来说处理的速度很快,但耗费较多系统资源,面对大量用户请求时容易造成系统压力。单线程由一个线程来处理多个用户请求,进程的重复利用极大地节约资源,面对大量用户也无压力。一般来讲,多进程需要线程安全Thread Safe,单进程无需线程安全None Thread Safe。

以上只是CGI的基本工作原理,就像初中课本上讲了发动机的工作方式,而实际生产出来的发动机在同样原理下却有各自的更复杂的实现方式。目前CGI的实现方式有ISAPI,FastCGI,CGI等多种方式。

 ISAPI(Internet Server Application Programming Interface)是微软IIS提供的一个接口,执行方式是以DLL动态库的形式使用,可以在被用户请求后执行,在处理完一个用户请求后不会马上消失,所以需要进行线程安全检查,这样来提高程序的执行效率,所以如果是以ISAPI来执行PHP,建议选择Thread Safe版本;ISA 的系统开销比 CGI 应用程序低,因为它们不要求创建其他进程,也不执行需要越过进程边界的通信

FastCGI 像是一个常驻 (long-live) 型的 CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去 fork 。一次执行方式是以单一线程来执行操作,所以不需要进行线程的安全检查,除去线程安全检查的防护反而可以提高执行效率,所以,如果是以FastCGI来执行PHP,建议选择Non Thread Safe版本。

NSAPI(Network Service Access Point Identifier/Netscape Server Application Programming Interface)由Netscape开发,沧桑的过往,不提。

CGI 略。

IIS

在IIS服务器下一般PHP配置成以ISAPI的方式来运行,得益于多线程处理在该模式下运行速度比较快。但常用的PHP扩展在ISAPI的方式运行时与IIS兼容性不好,因此在IIS下可选用陈旧的CGI模式,效率低下是显而易见的。

为了兼顾IIS下PHP的效率和安全,微软也采用了FastCGI。FastCGI可以让进程重复利用,也可以允许几个进程同时执行,运行效率好很多。

在IIS服务器环境下,如果是使用ISAPI的方式来运行PHP就必须用Thread Safe(线程安全)的版本,而用FastCGI模式运行PHP的话就没有必要用线程安全检查了,用None Thread Safe(NTS,非线程安全)的版本。总体来看ISAPI像是一种妥协,让PHP在IIS上能运行起来但也两者冲突依然存在。未来则是FastCGI的,得到微软的首肯,在IIS6、7版本中均可安装配置。

Apache

Linux系统下Apache做为服务器,PHP同样有多种工作模式,有Apache自带的APACHE2HANDLER,FastCGI,CGI 等。具体采用的工作方式可通过httpd -l 进行查看鉴别。

Apache2Handle是Apache 自带运行PHP的方式。Apache服务器在系统启动后,预先生成多个进程副本驻留在内存中。一旦有请求出现,就立即使用这些空余的子进程进行处理,这种方式不存在生成子进程造成的延迟。这些服务器副本在处理完一次HTTP请求之后并不立即退出,而是停留在计算机中等待下次请求。对于客户浏览器的请求反应更快,性能较高。

CGI遇到连接请求先要创建cgi的子进程,然后处理请求,完后结束该子进程,这就是fork-and-execute模式。CGI方式下服务器有多少连接请求就会有多少CGI子进程。子进程反复加载导致性能低下,系统资源占用率高。

FastCGI像是一个常驻(long-live)型的CGI,它激活后可以一直执行,不会每次都要花费时间去fork一次。PHP使用PHP-FPM(FastCGI Process Manager),全称PHP FastCGI进程管理器进行管理。

Windows系统下,Apache工作模式是mod_win32 或 FastCGI

在mod_win32模式下通过mpm_winnt.c实现多线程。mpm_winnt.c专门针对Windows NT优化的MPM(多路处理模块),它使用一个单独的父进程产生一个单独的子进程,在这个子进程中轮流产生多个线程来处理请求。mpm_winnt只能启动父子两个进程, 不能像Linux下那样同时启动多个进程。

FastCGI需要自行配置,方法参见  http://blog.csdn.net/amsong/article/details/39325955

针对不同模式先线程安全的选择,相信读者已经有了答案。

你可能感兴趣的:(从了解CGI来为PHP选择线程安全和非线程安全)