PHP 中什么是线程安全或非线程安全?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1623914/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 03:17:51  来源:igfitidea点击:

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

phpmultithreadingpackagethread-safetythreadcontext

提问by O..

I saw different binaries for PHP, like non-thread or thread safe?

我看到了不同的 PHP 二进制文件,比如非线程或线程安全的?

What does this mean?

这是什么意思?

What is the difference between these packages?

这些包有什么区别?

回答by Amr Mostafa

Needed background on concurrency approaches:

并发方法所需的背景知识:

Different web servers implement different techniques for handling incoming HTTP requests in parallel. A pretty popular technique is using threads -- that is, the web server will create/dedicate a single thread for each incoming request. The Apache HTTP web server supports multiple models for handling requests, one of which (called the worker MPM) uses threads. But it supports another concurrency model called the prefork MPM which uses processes -- that is, the web server will create/dedicate a single process for each request.

不同的 Web 服务器采用不同的技术来并行处理传入的 HTTP 请求。一种非常流行的技术是使用线程——也就是说,Web 服务器将为每个传入的请求创建/专用一个线程。Apache HTTP Web 服务器支持多种处理请求的模型,其中之一(称为工作 MPM)使用线程。但它支持另一种称为 prefork MPM 的并发模型,它使用进程——也就是说,Web 服务器将为每个请求创建/专用一个进程。

There are also other completely different concurrency models (using Asynchronous sockets and I/O), as well as ones that mix two or even three models together. For the purpose of answering this question, we are only concerned with the two models above, and taking Apache HTTP server as an example.

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

Needed background on how PHP "integrates" with web servers:

需要有关 PHP 如何与 Web 服务器“集成”的背景知识:

PHP itself does not respond to the actual HTTP requests -- this is the job of the web server. So we configure the web server to forward requests to PHP for processing, then receive the result and send it back to the user. There are multiple ways to chain the web server with PHP. For Apache HTTP Server, the most popular is "mod_php". This module is actually PHP itself, but compiled as a module for the web server, and so it gets loaded right inside it.

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

There are other methods for chaining PHP with Apache and other web servers, but mod_php is the most popular one and will also serve for answering your question.

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

You may not have needed to understand these details before, because hosting companies and GNU/Linux distros come with everything prepared for us.

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

Now, onto your question!

现在,进入你的问题!

Since with mod_php, PHP gets loaded right into Apache, if Apache is going to handle concurrency using its Worker MPM (that is, using Threads) then PHP must be able to operate within this same multi-threaded environment -- meaning, PHP has to be thread-safe to be able to play ball correctly with Apache!

由于使用 mod_php,PHP 会直接加载到 Apache 中,如果 Apache 将使用其 Worker MPM(即使用线程)处理并发,那么 PHP 必须能够在同一个多线程环境中运行——这意味着,PHP 必须是线程安全的,以便能够与 Apache 正确打球!

At this point, you should be thinking "OK, so if I'm using a multi-threaded web server and I'm going to embed PHP right into it, then I must use the thread-safe version of PHP". And this would be correct thinking. However, as it happens, PHP's thread-safety is highly disputed. It's a use-if-you-really-really-know-what-you-are-doing ground.

此时,您应该会想“好吧,如果我使用的是多线程 Web 服务器并且我打算将 PHP 直接嵌入其中,那么我必须使用 PHP 的线程安全版本”。这将是正确的想法。然而,碰巧的是,PHP 的线程安全性备受争议。这是一个如果你真的知道你在做什么的用途。

Final notes

最后笔记

In case you are wondering, my personal advice would be to notuse PHP in a multi-threaded environment if you have the choice!

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

Speaking only of Unix-based environments, I'd say that fortunately, you only have to think of this if you are going to use PHP with Apache web server, in which case you are advised to go with the prefork MPM of Apache (which doesn't use threads, and therefore, PHP thread-safety doesn't matter) and all GNU/Linux distributions that I know of will take that decision for you when you are installing Apache + PHP through their package system, without even prompting you for a choice. If you are going to use other webservers such as nginxor lighttpd, you won't have the option to embed PHP into them anyway. You will be looking at using FastCGIor something equal which works in a different model where PHP is totally outsideof the web server with multiple PHP processes used for answering requests through e.g. FastCGI. For such cases, thread-safety also doesn't matter. To see which version your website is using put a file containing <?php phpinfo(); ?>on your site and look for the Server APIentry. This could say something like CGI/FastCGIor Apache 2.0 Handler.

仅说基于 Unix 的环境,我想说幸运的是,如果您打算将 PHP 与 Apache Web 服务器一起使用,您只需考虑这一点,在这种情况下,建议您使用 Apache 的 prefork MPM(即不使用线程,因此,PHP 线程安全无关紧要)和我所知道的所有 GNU/Linux 发行版都会在您通过其软件包系统安装 Apache + PHP 时为您做出决定,甚至不会提示您为了一个选择。如果您打算使用其他网络服务器,例如nginxlighttpd,则无论如何您都无法选择将 PHP 嵌入其中。您将考虑使用FastCGI或类似的东西,它在 PHP 完全在外部的不同模型中工作具有多个 PHP 进程的 Web 服务器用于通过例如 FastCGI 响应请求。对于这种情况,线程安全也无关紧要。要查看您的网站使用的是哪个版本,请<?php phpinfo(); ?>在您的网站上放置一个包含该文件的文件并查找该Server API条目。这可以说类似于CGI/FastCGIApache 2.0 Handler

If you also look at the command-line version of PHP -- thread safety does not matter.

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

Finally, if thread-safety doesn't matter so which version should you use -- the thread-safe or the non-thread-safe? Frankly, I don't have a scientific answer! But I'd guess that the non-thread-safe version is faster and/or less buggy, or otherwise they would have just offered the thread-safe version and not bothered to give us the choice!

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

回答by Greg

For me, I always choose non-thread safeversion because I always use nginx, or run PHP from the command line.

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

The non-thread safe version should be used if you install PHP as a CGI binary, command line interface or other environment where only a single thread is used.

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

A thread-safe version should be used if you install PHP as an Apache module in a worker MPM (multi-processing model) or other environment where multiple PHP threads run concurrently.

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

回答by J. M. Becker

Apache MPM prefork with modphp is used because it is easy to configure/install. Performance-wise it is fairly inefficient. My preferred way to do the stack, FastCGI/PHP-FPM. That way you can use the much faster MPM Worker. The whole PHP remains non-threaded, but Apache serves threaded (like it should).

使用带有 modphp 的 Apache MPM prefork 是因为它易于配置/安装。在性能方面,它是相当低效的。我首选的堆栈方式是 FastCGI/PHP-FPM。这样你就可以使用更快的 MPM Worker。整个 PHP 仍然是非线程的,但 Apache 服务于线程(就像它应该的那样)。

So basically, from bottom to top

所以基本上,从下到上

Linux

Linux

Apache + MPM Worker + ModFastCGI (NOT FCGI) |(or)| Cherokee |(or)| Nginx

Apache + MPM Worker + ModFastCGI(非 FCGI)|(或)| 切诺基|(或)| nginx

PHP-FPM + APC

PHP-FPM + APC

ModFCGI does not correctly support PHP-FPM, or any external FastCGI applications. It only supports non-process managed FastCGI scripts. PHP-FPM is the PHP FastCGI process manager.

ModFCGI 不能正确支持 PHP-FPM 或任何外部 FastCGI 应用程序。它只支持非进程管理的 FastCGI 脚本。PHP-FPM 是 PHP FastCGI 进程管理器。

回答by Somnath Muluk

As per PHP Documentation,

根据PHP 文档

What does thread safety mean when downloading 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.

线程安全意味着二进制文件可以在多线程网络服务器上下文中工作,例如 Windows 上的 Apache 2。线程安全的工作原理是在每个线程中创建一个本地存储副本,这样数据就不会与另一个线程发生冲突。

那我选择什么?如果您选择将 PHP 作为 CGI 二进制文件运行,那么您将不需要线程安全,因为该二进制文件在每次请求时都会被调用。对于多线程 Web 服务器,例如 IIS5 和 IIS6,您应该使用 PHP 的线程版本。

Following Libraries are not thread safe. They are not recommended for use in a multi-threaded environment.

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

  • SNMP (Unix)
  • mSQL (Unix)
  • IMAP (Win/Unix)
  • Sybase-CT (Linux, libc5)
  • SNMP (Unix)
  • mSQL (Unix)
  • IMAP (Win/Unix)
  • Sybase-CT (Linux, libc5)