php内核,如何理解ts和nts的区别?如何选择?
发布于 作者:苏南大叔 来源:程序如此灵动~在做php
内核编译的时候,总是有个傻傻不清楚的选项,叫做"线程安全"选项。分别是:“非线程安全nts”和“线程安全ts/zts”。是的,zts
就是ts
就是“线程安全”,“线程不安全”就是nts
。那么,具体上来说,它们到底有啥区别呢?是不是“线程安全”一定比“线程不安全”更好呢?nts
不安全的版本可以线上使用么?
大家好,这里是苏南大叔的“程序如此灵动”博客,这里讲述苏南大叔和计算机代码的故事。本文讲述,php
内核编译的"线程安全"问题。其实,这个内容应该是比较深奥的话题,不过目前以苏南大叔的理解,还只能停留于表面。所以,本文的内容仅供参考。测试环境:phpsrc@7.4.28
。
写在前面
大部分情况下,phper
对于这个“线程安全”的选项,是无感的。所以,它必然不会是个啥大的问题。只是在编译或者使用一些“pecl extension”的时候,会因为“线程安全”这个选项不匹配,导致扩展初始化失败。这个时候,才会想起来看看这个线程安全到底是个啥东东。
名称 | 中文 | 英文 |
---|---|---|
ts/zts | 线程安全 | Zend Thread Safe |
nts | 非线程安全 | None Thread Safe |
而且“线程不安全”也并不是如狼似虎的bug
存在,而且在某些情况下,官方还推荐使用“非线程安全”(aka:nts
)版本的php
呢。所以,这个大家最关心的“非线程安全”问题,也并不是啥大事儿。在特定的场景下,线程不安全同时意味着效率的提升。那么,“非线程安全”也是有应用场景的。
线程安全问题,指的就是:多线程环境下如何安全存取公共资源。在C
中,当一个变量被声明在任何函数之外时,就成为一个全局变量,这时这个变量会被分配到进程的共享存储空间,不同线程都引用同一个地址空间,因此一个线程如果修改了这个变量,就会影响到全部线程。这看似为线程共享数据提供了便利,但是PHP往往是每个线程处理一个请求,因此希望每个线程拥有一个全局变量的副本,而不希望请求间相互干扰。早期的PHP往往用于单线程环境,每个进程只启动一个线程,因此不存在线程安全问题。后来出现了多线程环境下使用PHP的场景,因此Zend引入了Zend线程安全机制(Zend Thread Safety,简称ZTS)用于保证线程的安全。
官方态度
至于推荐使用哪款php
,这个也是要看官方的态度的,苏南大叔来举例一下官方的相关表述。在windows.php.net
上面,有下面的表述,参考下述页面的左侧边栏位置。
If you are using PHP as FastCGI with IIS you should use the Non-Thread Safe (NTS) versions of PHP.With Apache, using the apache2handler SAPI, you have to use the Thread Safe (TS) versions of PHP.
意思就是iis
下面使用fastcgi
,推荐使用nts
版本。apache
下面,使用sapi
方式,推荐ts
版本。
TS refers to multithread capable builds. NTS refers to single thread only builds. Use case for TS binaries involves interaction with a multithreaded SAPI and PHP loaded as a module into a web server. For NTS binaries the widespread use case is interaction with a web server through the FastCGI protocol, utilizing no multithreading (but also for example CLI).
意思就是:sapi
和module
加载php
的,用ts
版本。fastcgi
和cli
形式的,就要用nts
版本。对于大家最常见的组合:nginx
+php-fpm
,fpm
的全称是FastCGI Process Manager
。所以,fastcgi
=》nts
版本是推荐的。
上边的意思,经过苏南大叔理解组合完成后,是下面这个表格(如有不妥,请留言,谢谢):
组合 | 官方推荐版本 |
---|---|
sapi | ts |
module | ts |
apache=>sapi | ts |
fastcgi | nts |
fpm [最常见] | nts |
cli | nts |
iis=>fastcgi | nts |
编译参数
对于configure
编译的参数这一步,是可以用来控制到底是zts
还是nts
的。
前不久苏南大叔编译的phpsrc@7.4.28
为例来说,默认是ts
版本。如果要编译nts
版本的话,需要设置:
configure --disable-zts
当然,参数还是要以--help
为准。
configure --help
win
环境下:
configure.bat --help
参考文献
综述
本文仅从表象上进行了分析,并没有深入探讨事情的本质,仅供参考。更多php
内核编译的文章,请点击:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。