关于多线程:PHP中什么是线程安全的或非线程安全的?

What is thread safe or non-thread safe in PHP?

我看到了不同的PHP二进制文件,比如非线程或线程安全的?这是什么意思?这些包裹有什么区别?


关于并发方法的必要背景:

不同的Web服务器实现了并行处理传入HTTP请求的不同技术。一种非常流行的技术是使用线程——也就是说,Web服务器将为每个传入的请求创建/专用一个线程。ApacheHTTP Web服务器支持多个模型来处理请求,其中一个模型(称为workerMPM)使用线程。但是它支持另一个并发模型,叫做PreforkMPM,它使用进程——也就是说,Web服务器将为每个请求创建/专用一个进程。

还有其他完全不同的并发模型(使用异步套接字和I/O),以及将两个甚至三个模型混合在一起的模型。为了回答这个问题,我们只关注上面的两个模型,并以ApacheHTTP服务器为例。

需要了解PHP如何与Web服务器"集成"的背景:

PHP本身不响应实际的HTTP请求——这是Web服务器的工作。因此,我们将Web服务器配置为将请求转发到PHP进行处理,然后接收结果并将其发送回用户。有多种方法可以用PHP链接Web服务器。对于ApacheHTTP服务器,最流行的是"mod_php"。这个模块实际上是PHP本身,但是编译为Web服务器的一个模块,因此它就可以直接加载到其中。

还有其他方法可以将PHP与Apache和其他Web服务器链接起来,但mod_php是最流行的方法,也可以用来回答您的问题。

您可能以前不需要了解这些细节,因为托管公司和GNU/Linux发行版为我们准备了一切。

现在,回答你的问题!

由于有了mod_php,php就可以直接加载到apache中,如果apache要使用它的工作进程mpm(即使用线程)来处理并发性,那么php必须能够在相同的多线程环境中运行——也就是说,php必须是线程安全的,才能正确地使用apache玩球!

此时,您应该在想"好吧,如果我使用的是多线程的Web服务器,我要将PHP直接嵌入其中,那么我必须使用PHP的线程安全版本"。这是正确的想法。然而,事实上,PHP的线程安全性是有争议的。如果你真的知道自己在做什么,这是一个有用的方法。

期末笔记

如果您想知道,我的个人建议是,如果您有选择的话,不要在多线程环境中使用PHP!

只谈到基于Unix的环境,我想说幸运的是,如果您要将PHP与Apache Web服务器一起使用,那么您只需要考虑一下这个问题,在这种情况下,建议您使用Apache的预处理MPM(它不使用线程,因此,PHP线程安全无关紧要),以及我所知道的所有GNU/Linux发行版。当您通过他们的包系统安装apache+php时,甚至不需要提示您进行选择,就可以做出这个决定。如果您要使用其他Web服务器,如nginx或lighttpd,则无论如何都不能选择将php嵌入其中。您将看到使用fastcgi或其他类似的方法,该方法在另一个模型中工作,其中php完全不在Web服务器上,有多个php进程用于通过fastcgi来响应请求。对于这种情况,线程安全也不重要。要查看您的网站使用的是哪个版本,请在您的网站上放置一个包含的文件,并查找Server API条目。这可以说类似于CGI/FastCGIApache 2.0 Handler

如果您还查看PHP的命令行版本——线程安全无关紧要。

最后,如果线程安全无关紧要,那么应该使用哪个版本——线程安全还是非线程安全?坦白说,我没有科学的答案!但是我猜非线程安全版本更快和/或更少的错误,否则他们只会提供线程安全版本,而不会费心给我们选择!


对于我来说,我总是选择非线程安全版本,因为我总是使用nginx,或者从命令行运行php。

如果将PHP安装为CGI二进制文件、命令行接口或仅使用单个线程的其他环境,则应使用非线程安全版本。

如果将PHP作为Apache模块安装在Worker MPM(多处理模型)或其他同时运行多个PHP线程的环境中,则应使用线程安全版本。


使用带modphp的ApacheMPM预处理是因为它易于配置/安装。从性能角度看,这是相当低效的。我的首选方法是fastcgi/php-fpm。这样你就可以使用速度更快的MPM工作者。整个PHP仍然是非线程的,但是Apache提供线程服务(就像它应该的那样)。

所以基本上,从下到上

Linux

apache+mpm工人+modfastcgi(非fcgi)(或)cherokee(或)nginx

PHPFPM+APC

modfcgi不正确支持php-fpm或任何外部fastcgi应用程序。它只支持非进程管理的fastcgi脚本。php-fpm是php fastcgi进程管理器。


根据PHP文档,

下载PHP时线程安全意味着什么?

Thread Safety means that binary can work in a multithreaded webserver
context, such as Apache 2 on Windows. Thread Safety works by creating
a local storage copy in each thread, so that the data won't collide
with another thread.

So what do I choose? If you choose to run PHP as a CGI binary, then
you won't need thread safety, because the binary is invoked at each
request. For multithreaded webservers, such as IIS5 and IIS6, you
should use the threaded version of PHP.

以下库不是线程安全的。不建议在多线程环境中使用它们。

  • SNMP(UNIX)
  • MSQL(UNIX)
  • IMAP(WIN/UNIX)
  • Sybase CT(Linux、libc5)