该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2009-02-03
robbin 写道 如果PHP要实现跨请求的持有内存资源,这意味着PHP必须实现对象内存分配机制和垃圾收集器,而这将意味着PHP语言的复杂性上升,PHP内存泄露的危险大大增加,最终将得不偿失。 其实我们应该跳出编程语言的简单对比,而比较一下不同的编程模型背后的哲学: 1、Java - controll whole world模型 单进程运行,进程内部多线程调度,所有的资源都自己提供。 2、Ruby - controll process模型 多进程运行,进程内部可以持有资源,带有GC,部分依赖外部资源实现(例如Cache)功能 3、PHP - controll request模型 多进程运行,进程不持有任何资源,不带GC,完全依赖外部资源实现扩展功能 比较和探讨一下3种不同的模型,以及他们的优势,劣势,长处,短处,适合做什么,不适合做什么。这才是一个有意思的话题。 谢谢, 我一直在找PHP的线程模型方面的资料.今天看这个帖子才知道PHP的处理这么"省事". |
|
返回顶楼 | |
发表时间:2009-02-03
另外, 还想问下:
1.java(单进程运行)是不是所有请求都用一个进程处理, 每个请求用这个进程中的一个线程处理? 2. Ruby(多进程运行)是不是类似进程池? 没有空闲进程则创建, 有就重用? 3. PHP的多进程运行方式最好理解, 但有没有办法实现"定时执行后台任务"? 以及"异步调用"? |
|
返回顶楼 | |
发表时间:2009-02-03
Ruby 也可以跟 Java 一样:“controll whole world模型 单进程运行,进程内部多线程调度,所有的资源都自己提供”。
“controll process模型 多进程运行,进程内部可以持有资源,带有GC,部分依赖外部资源实现(例如Cache)功能”不是 Ruby,而是 rails 的运行方式。 |
|
返回顶楼 | |
发表时间:2009-02-03
引用 建议看看这篇博文:http://blog.ianbicking.org/2008/01/12/what-php-deployment-gets-right/ 这篇文章写漏了一个关键的 fastcgi。fastcgi 模式下,php 不需要对每个请求都建立进程。 |
|
返回顶楼 | |
发表时间:2009-02-03
最后修改:2009-02-03
icewubin 写道 dualface 写道 b) 尽可能降低 bootstrap 成本:bootstrap 通常完成运行环境初始化、载入配置、连接数据库等。在 PHP 中,初始化运行环境并不存在什么问题,因为 PHP 本就是为 Web 应用设计的,启动 .php 程序时,运行环境就已经准备好了。而载入配置可以通过把配置文件解析为 php 数组后写入缓存文件,载入时直接 include 就可以获得设置,连序列化和反序列化都省了。最后的数据库连接,通过持久连接就能很好解决。而且访问量大了,再增加个第三方的连接池也不是难事。
1.框架的逻辑环境可简单可复杂,本质上来讲是在内存中建立数据结构模型,即使你说的,针对配置文件的加载在文本处理上可以优化,逻辑上的数据结构建立的开销是无法避免的。比如,处理一个大的xml对象(算是第三个具体的例子了,呵呵),深度优先或广度优先算法遍历这个xml对象,变成一定的数据结构(假设某个功能框架有这个需求),这个数据结构的建立过程是很难避免的。 当然可以根据PHP的特性,通过其他手段绕过这个问题,但毕竟是绕过这个问题。 这和框架有什么关系?莫名其妙 引用 2.配置文件和数据库连接共享只不过是框架逻辑环境初始化的两个例子而已。从这两个例子的对策上来说,已经把PHP搞得有点复杂了,你说得很简单,什么都很好解决,但是当很多“很好解决”的技术手段或方案合在一起,往往就不是那么很好解决了,技术架构也越来越复杂。 你用 php 框架实际做过项目再来说这话不迟。处男说做爱没意思,不是扯淡么。 你的话我也不想回了,纯粹是在抬杠。 |
|
返回顶楼 | |
发表时间:2009-02-03
zaqwe 写道 另外, 还想问下:
1.java(单进程运行)是不是所有请求都用一个进程处理, 每个请求用这个进程中的一个线程处理? 2. Ruby(多进程运行)是不是类似进程池? 没有空闲进程则创建, 有就重用? 3. PHP的多进程运行方式最好理解, 但有没有办法实现"定时执行后台任务"? 以及"异步调用"? 第三个我可以回答:如果是虚拟主机,只能模仿 cron。如果是自己的服务器,写个 php 脚本从 cron 调用就行了。至于异步调用确实做不到,只能用 ajax 或者队列+cron脚本来模拟。 |
|
返回顶楼 | |
发表时间:2009-02-03
lao__wang 写道 diogin 写道 建议看看这篇博文:http://blog.ianbicking.org/2008/01/12/what-php-deployment-gets-right/ 从 Python/Ruby 和 PHP 的运行模型来看,我的建议是初、中、高级开发者均可使用 PHP,而中、高级开发者比较偏向于使用 Python/Ruby,因为后者给开发者一种从全局上掌控工作进程的快感,这种快感是无法从 PHP 的运行模型中得到的。 做个比喻: Python/Ruby 框架是一群音乐家静静地坐着演奏交响乐,而 PHP 框架是一群舞者在激流而下的瀑布里跳舞…… 这些舞者可以模仿那些音乐家的“模式”,却模仿不了他们的“本质”,而只有这个“本质”,才是他们的“模式”赖以生存的基础。 我同意这种观点:Python/Ruby 框架是在误导 PHP 框架。 还有几个不明白的地方: 如果性能不是问题,那PHP框架还是不是问题? 运行机制上,上面说的给开发者一种从全局上掌控工作进程的快感,能不能举一个实际的例子解释一下,到底是什么全局掌控?PHP是否有必要实现这样的全局掌控? PHP 框架不是问题。关键是要找到一条“建设有 PHP 特色的框架开发之路”,而不是“照搬资本主义”。社会体质的不同造成了中国与大部分欧美国家发展之路的差异,中国经历了几代领导人才找到真正的出路,这点跟 PHP 目前的情况类似:PHP 的实现本质上就跟 Python/Ruby 的实现不同。 运行机制上的例子,随便举几个吧:你可以用 Python 脚本操纵线程,可以实现跨请求存在的变量,实现真正的对象(进程内对象,而非请求内对象,PHP 的类实际上只是一个跟请求有着相同生命期的瞬态对象,PHP 的对象就更不用说了),实现真正的工作单元模式(严肃的 ORM 都需要这个),实现真正的对象池、连接池、线程池,实现真正的异步I/O、非阻塞I/O,等等等等,你可以想象一下你用 C 写 HTTP Server 时需要考虑哪些,你就可以用 Python 去实现。 然而……你能单纯用 PHP 脚本实现这些么?PHP 解释器的实现注定了它只适合 HTTP 这种请求、响应的运行方式,你的全部表演已经被套牢在 PHP 解释器设计的运行环境里。你没法控制 PHP 工作进程。当然,从工业开发来说,这种做法非常好,因为它限定了程序员只能做什么,即使程序猿本身并不知道它已经被限死了。不过大部分程序猿也非常乐于被限制住,因此实际上还是皆大欢喜的,不然也不会有这么多 PHP 程序员,PHP 也不会这么流行。 反之,Python/Ruby 是做为通用的应用程序开发语言而设计的,它没有为 HTTP 这种请求、响应式运行模型做设计,因此你必须考虑很多东西,比如 PHP 解释器已经实现了 mod_php、FastCGI 的 SAPI,实现了 HTTP 这种请求、响应模型,你只需选择一个即可快速开发 Web 应用程序,然而换成 Python 则不行,即使你有了 Python 解释器及其标准库,在应用到 Web 平台上时你要做 Web 开发还需要做很多其它东西,比如你可能没有 FastCGI 协议的实现,你得去实现它;你可能没有 HTTP 请求的 parser,你得去实现它;没有模板渲染器,你也得去渲染它;你希望你的 Python 应用程序可以在多种 Web 服务器平台上部署,你得实现 WSGI 协议;你希望你的程序跑一段时间后不会挂,你得考虑资源的分配和释放…… 当然,现在已经有很多人完成了这些工作,所以现在用 Python 开发 Web 应用程序已经相当容易了。然而如果你决定开发一个严肃的 Python Web 框架,那难度相比起 PHP 就要高不少,没有系统的计算机科学知识体系较难做到,因为类比开来,就是你需要去实现 PHP 解释器已经帮你实现好的很多东西。 当然,两者都有优、缺点,我目前也是两者都用。 |
|
返回顶楼 | |
发表时间:2009-02-03
不错,PHP 的优势在于其设计目标就是“Web”,所以开发 Web 应用需要的大部分基础功能,PHP 都已经做好了。
以上传文件来说,PHP 是内置的,绝大部分情况已经够用了。而其他语言的 Web 框架都得自己去实现这些,就连 ASP 也得自己做。 所以 PHP 的开发框架其实着重点是如何简化业务功能的开发,不用去考虑那么多基础性工作。当然正如你所说,由于 PHP 运行模式的限制,工作单元、对象池、连接池、线程池,实现真正的异步I/O、非阻塞I/O等在 PHP 框架中都没法做。 不过就因为这几点就认为 PHP 框架是误入歧途,毫无疑问是太片面了。PHP 框架虽然有模仿其他语言的开发框架,但本质上 PHP 框架还是以发挥 PHP 自身优势为主。 事实上,在今天看来,CakePHP 这样的 PHP 框架不管是设计还是实现,都已经过时了。相信会有更具备“PHP 特色的开发框架”出现。 |
|
返回顶楼 | |
发表时间:2009-02-03
dualface 写道 引用 建议看看这篇博文:http://blog.ianbicking.org/2008/01/12/what-php-deployment-gets-right/ 这篇文章写漏了一个关键的 fastcgi。fastcgi 模式下,php 不需要对每个请求都建立进程。 FastCGI 的行为跟 mod_php 没有什么差异,除了 mod_php 还可以选择线程模式来运行。PHP 的 FastCGI SAPI 目前我还没看到以多线程模式来运行的,常用的 php-fpm 也是以多进程单线程来运行的。 嵌入 mod_php 的 httpd 子进程同样是持久的,不是一个请求过来就建立进程,那是 CGI 的做法。 那篇博文说 PHP 类似 CGI 的意思是说 PHP 脚本的行为类似 CGI,因为 CGI 进程的生命周期也是一次请求,这点跟 PHP 脚本的一次执行是一致的。实现上,PHP 解释器实现了一个“CGI进程运行环境”,只是在其中运行的角色是 PHP 脚本。 |
|
返回顶楼 | |
发表时间:2009-02-03
zaqwe 写道 robbin 写道 如果PHP要实现跨请求的持有内存资源,这意味着PHP必须实现对象内存分配机制和垃圾收集器,而这将意味着PHP语言的复杂性上升,PHP内存泄露的危险大大增加,最终将得不偿失。 其实我们应该跳出编程语言的简单对比,而比较一下不同的编程模型背后的哲学: 1、Java - controll whole world模型 单进程运行,进程内部多线程调度,所有的资源都自己提供。 2、Ruby - controll process模型 多进程运行,进程内部可以持有资源,带有GC,部分依赖外部资源实现(例如Cache)功能 3、PHP - controll request模型 多进程运行,进程不持有任何资源,不带GC,完全依赖外部资源实现扩展功能 比较和探讨一下3种不同的模型,以及他们的优势,劣势,长处,短处,适合做什么,不适合做什么。这才是一个有意思的话题。 谢谢, 我一直在找PHP的线程模型方面的资料.今天看这个帖子才知道PHP的处理这么"省事". PHP 脚本里没有线程的概念,只有 PHP 解释器的实现有线程与否的概念。PHP 解释器通过 TSRM 层来实现对 PHP 脚本屏蔽线程。 另外,PHP 解释器未必使用多进程的运行方式。在 Apache 下,它还可以嵌入多线程方式的 httpd 子进程,以多线程的方式来运行,一个线程对应一个 HTTP 请求的处理。当然此时如果 PHP 解释器的部分代码没有做到线程安全,那可能就会出问题(据称 PHP 解释器的核心部分都是线程安全的,不过可能有些扩展代码的质量不高,存在线程不安全的问题)。 关于 PHP 部分,robbin的说法基本是错误的。PHP 解释器进程持有它需要的所有资源,它也带 GC。 PHP 解释器进程有两层面的 GC,一层是在请求结束时必须释放所有该次请求内申请的资源,并清扫该次环境;另一层是在请求执行内,它也存在 GC,这就是通常所说的 GC,比如变量的引用计数实现。 |
|
返回顶楼 |
已被评为好帖!
|