php不支持多线程,所以不用考虑并发问题?这句话,对吗

如题,能否给出详细的理由,谢过。

阅读 24.9k
7 个回答

其实这句话本身是歧义的。

首先看前提条件:

php不支持多线程

PHP 语言代码本身(大部分情况下)是不关心自身是多进程还是多线程的。但,这并不表示 PHP 不支持多线程/多进程。php-fpm 就是多进程单线程的,apeche 的多线程模式就是多线程的。PHP 只是一般不会在 PHP 代码级别直接控制进程或者线程。

不用考虑并发问题

前提不成立,结论也就没有什么因果关系了。
我理解说这句话的人的本意是:因为 PHP 一般不支持控制进程、线程,所以也不会从直接通过代码控制进程、线程来应对并发问题。
这么说是没什么问题的。

但是,并发问题还依旧是并发问题,不会因为 PHP 代码本身不太支持解决并发问题,并发问题就不存在的。
解决 PHP 的并发问题常规方式是通过各种配置的调整(nginx.conf, php-fpm.ini, php.ini)、然后就是负载均衡之类的方式来解决的。这些不是 PHP 代码,但是是与 PHP 相关密切的东西,作为 PHPer 也是需要掌握的。

另外,针对具体的业务类型修改 PHP 逻辑,甚至前端调用逻辑也是有的。还有包括 swoole 之类彻底抛弃 php-fpm 的扩展方式,将 PHP 从基础上支持异步并发(然而还是单线程)。这些并发优化方式就要针对具体业务来选择了。

php 自身不能够通过代码进行线程控制,但是依旧需要考虑并发问题,因为两者并没有联系。多线程只是同一时间执行多个线程任务,和并发没有直接关系。

简单的 nginx + php-fpm 模式:

  • 当客户端发送一个请求时,web server 会通过一个 php-fpm 进程(这里和下文所说指的 fpm 进程都是 fpm 开启的 worker 进程,关于 fpm 的工作原理这里不再累述)去执行 php 代码,php 代码的执行是单线程的。
  • 那么,当有多个客户端同时发送请求时(并发),web server 就会为每个请求分配一个 php-fpm 进程去执行 php 代码。
  • 请求执行过后,对应的 php-fpm 进程内存得以回收释放。
  • 而并发的问题在于,在某一时间,客户端请求占满了所有 php-fpm 进程,这个时候,新来的请求只能等待空闲的 php-fpm 来处理,这就是 多进程同步阻塞模型 的弊端,当然还有进程过多所带来的内存占用问题。

PHP本来就支持多线程呀,所以才有线程安全和非线程安全的区别.
PHP的多线程扩展请看:
https://pecl.php.net/package/pthreads
这个扩展提供了实实在在的PHP多线程编程支持,一般用于cli下的脚本编程.
另外国人峰哥还开发了一个提供了异步多线程架构支持用PHP开发高性能实时网络服务的扩展Swoole:
https://pecl.php.net/package/swoole
Swoole里的多线程并不需要编程者关心,它更像一套架构,你只需配置,Swoole一般也是用于cli下的脚本编程.

像经常跟Nginx配合使用的PHP FastCGI服务PHP-FPM是使用多进程实现利用多核应对并发,跟采用prefork MPM的Apache类似.PHP-FPM支持进程池设置,支持静态和动态的进程数量设置,支持天然的透明的"数据库连接池"(持久连接):
222219_6hEX_561214.jpg

MOD_PHP搭配采用event MPM的Apache跑的时候也是工作于多线程状态,因为Apache event MPM是一个多进程多线程事件驱动的MPM,这是PHP需要使用线程安全版本.

错,牛头不对马嘴!

PHP是不支持多线程,但是命令行程序的后台运行或web应用程序的php-fpm都可以是多进程并发处理的,所以避免不了产生并发问题,比如一个订单就1个库存,两个并发请求同时上来你如何保证订单不超卖?

并发只有多线程?这也太狭隘了

新手上路,请多包涵

就算不考虑多线程 并发依然存在 并且更为难解决 还是要想办法去避免和优化的

平时说的并发多数是针对服务的,比如说 apache nginx
而不是说php
再加上 php是有多线程扩展的 只是平时项目中没有用到而已

定义多线程类 extends Thread

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏