PHP高性能开发-多进程开发

硬件多核时代的软件业
以前计算能力的提升一直在摩尔定律的指引下,沿着提升CPU时钟频率这条道路前进,从初期的几十MHz到如今的几GHz。但是,进入2002年以 来,CPU提升主频的困难越来越大,因为主频的提升带来了散热和功耗的大幅增加等问题。几年前,英特尔和AMD都调整了研究方向,开始研究在同一CPU中 放置多个执行内核。
尽管多核是一种硬件技术,但硬件和软件是相互依存的,硬件只是一种物质基础,只有有了软件的支持,才能使硬件拥有用武之地。如今,多核的优势已成共识:一在于“降低功耗”,解决了以往靠主频提高带来的后遗症问题;
二在于计算性能更强,能够满足用户同时进行多任务处理和多任务计算环境的要求。要发挥多核的这些优势,相应软件的支持必不可少。其中,最主要的就是软件程序要能够并行处理。

并发和并行的关系
并发和并行的区别就是一个处理器同时处理多个任务和多个处理器或者是多核的处理器同时处理多个不同的任务。前者是逻辑上的同时发生(simultaneous),而后者是物理上的同时发生.并发性(concurrency),又称共行性,是指能处理多个同时性活动的能力,并发事件之间不一定要同一时刻发生。并行(parallelism)是指同时发生的两个并发事件,具有并发的含义,而并发则不一定并行。
来个比喻:并发和并行的区别就是一个人同时吃三个馒头和三个人同时吃三个馒头。

进程与线程

什么是进程(Process),普通的解释就是,进程是程序的一次执行,而什么是线程(Thread),线程可以理解为进程中的执行的一段程序片段。在一个多任务环境中下面的概念可以帮助我们理解两者间的差别:

进程间是独立的,这表现在内存空间,上下文环境;线程运行在进程空间内。一般来讲(不使用特殊技术)进程是无法突破进程边界存取其他进程内的存储空间;而线程由于处于进程空间内,所以同一进程所产生的线程共享同一内存空间。

同一进程中的两段代码不能够同时执行,除非引入线程。线程是属于进程的,当进程退出时该进程所产生的线程都会被强制退出并清除。线程占用的资源要少于进程所占用的资源。进程和线程都可以有优先级。在线程系统中进程也是一个线程。可以将进程理解为一个程序的第一个线程。

现代的操作系统几乎都是多任务操作系统,我们通常使用的计算机中只有一个CPU,也就 是说只有一颗心,要让它一心多用,同时运行多个进程,就必须使用并发技术。实现并发技术相当复杂,最容易理解的是“时间片轮转进程调度算法”,它的思想简 单介绍如下:在操作系统的管理下,所有正在运行的进程轮流使用CPU,每个进程允许占用CPU的时间非常短(比如10毫秒),这样用户根本感觉不出来 CPU是在轮流为多个进程服务,就好象所有的进程都在不间断地运行一样。但实际上在任何一个时间内有且仅有一个进程占有CPU。 
如果一台计算机有多个CPU,情况就不同了,如果进程数小于CPU数,则不同的进程可以分配给不同的CPU来运行,这样,多个进程就是真正同时运行的,这便是并行。但如果进程数大于CPU数,则仍然需要使用并发技术。

如果在多CPU计算机中只运行一个进程(线程),就不能发挥多CPU的优势。那么在多CPU的硬件条件下,一个进程是不是会在多个CPU上运行呢?

其实这还是要明白  进程是系统进行资源分配和调度的单位  线程是操作系统分配处理器(CPU)时间的基本单元,是系统中最小的执行单元。一个进程被分配了独立的资源空间,但里面真正执行的还是一个一个线程,在运行一个进程的时候,它里的若干线程会被空间的CPU调度执行。 所以一个进程会在多CPU上运行,也就是你在一个多CPU上只行动一个程序,也会看到多CPU在不停的切换

动态语言的现状

在Python,Ruby中,如果我们愿意,我们完全可以像大多数的c,c++,java开发者一样,随时随地的使用线程。但问题是,Ruby,Python使用了一个Global Interpreter Lock(aka GIL).这个GIL是一个保护数据完整性的锁机制。GIL每次只允许数据被一个线程修改,因此不让线程损坏数据,也不允许其真正的并发运行。这就是为什 么有些人说,Ruby和Python并不具备真正的并发性。

多进程或者fork进程 ,这是使用Ruby和Python,PHP并发最常用的解决方案。因为默认的语言并没有能力实现真正的并发,或者因为你想避免线程编程的挑战,你可能想去开启更多的进程。如果你并不想在进程间共享状态,这是很容易的。[

大多数的编程语言都不容易实现并发,函数式语言简化了并行开发,如Erlang,Scala,Lisp,Clojure.这得益于它既不用共享内存,也不会产生副作用(side effect)的函数。

PHP多进程方法

1.exec或system

2.popen会创建一个管道来连接该进程,然后使用fread/fgets/stream_get_contents来读取该进程返回的结果。跟 exec或system之类的函数不同的是,exec会等待命令执行完成,再运行下面的代码,但popen不会。proc_open又更加强大一些,支持 stdin和stdout,路径设置等等。

3.PHP有一组进程控制函数(编译时需要 –enable-pcntl与posix扩展),使得php能在*nix系统中实现跟c一样的创建子进程、使用exec函数执行程序、处理信号等功能。 PCNTL使用ticks来作为信号处理机制(signal handle callback mechanism),可以最小程度地降低处理异步事件时的负载。何谓ticks?Tick 是一个在代码段中解释器每执行 N 条低级语句就会发生的事件,这个代码段需要通过declare来指定。

PHP实现守护进程

编写Daemon程序有一些基本的规则,以避免不必要的麻烦。

1、首先是程序运行后调用fork,并让父进程退出。子进程获得一个新的进程ID,但继承了父进程的进程组ID。

2、调用setsid创建一个新的session,使自己成为新session和新进程组的leader,并使进程没有控制终端(tty)。

3、改变当前工作目录至根目录,以免影响可加载文件系统。或者也可以改变到某些特定的目录。

4、设置文件创建mask为0,避免创建文件时权限的影响。

5、关闭不需要的打开文件描述符。因为Daemon程序在后台执行,不需要于终端交互,通常就关闭STDIN、STDOUT和STDERR。其它根据实际情况处理。

另一个问题是Daemon程序不能和终端交互,也就无法使用printf方法输出信息了。我们可以使用syslog机制来实现信息的输出,方便程序的调试。在使用syslog前需要首先启动syslogd程序,关于syslogd程序的使用请参考它的man page,或相关文档,我们就不在这里讨论了。

进程间通信IPC

Linux下进程间通信的几种主要手段简介:

  1. 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;
  2. 信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号 给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数 是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数);
  3. 报文(Message)队列(消息队列):消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字 节流以及缓冲区大小受限等缺点。
  4. 共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
  5. 信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
  6. 套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。

注意事项

  • PHP的内存管理机制
  • 进程IO异常
  • 资源fork问题
  • 通信的复杂度
  • 进程的僵尸回收机制

具体的例子是

1、最好结合cronjob来定时跑脚本,这样即使你的代码没有管理好内存,也不要紧,跑完一次就释放掉了。

2、对于必须常驻进程的脚本,一定要在while (1) {} 这样一个死循环里面运行代码。这样只要代码不出状况,脚本就不会停止。

3、echo 不能用,而是用log 代替。用写日志的方法代替echo。因为echo 是向屏幕输出一个字符,如果没有任何输出的对象,就会报一个致命错误。

4、如果MYSQL,要每次重新连接MYSQL或者至少使用时判断连接。因为你的脚本运行期间难保mysql不会重启,一旦重启,之前连接资源就失效了,会报这样一个错误:mysql has go away。

5、新产生的变量,没用了要马上释放。

6、 如果要访问文件,首先要 clearstatcache, 否则很有可能会不精确的统计,如果你频繁打开文件,文件的handle 值会不断增加,等到超过整数的最大值,程序就无法打开文件

PHP高性能开发-多进程开发,布布扣,bubuko.com

时间: 2025-01-14 02:56:08

PHP高性能开发-多进程开发的相关文章

高性能PHP应用开发-总结

最近将<高性能PHP应用开发>这本书看了两遍,觉得还是受益匪浅的,该书讲的面比较广,都是经验性的内容,建议大家有时间可以详细看一下的,基于此特意将本书的精华易用的部分加以整理,子曰:“温故而知新,可以为师矣.” [第一章  基准测试工具] 一:Apache Benchmark (ab) 随 apache包一起安装ab -n (请求数) -c (并发数,不能起过-n) -t (请求的秒数) http://url 报告中最重要的是以下字段内容:-------------------------HT

linux应用开发-多进程程序设计

linux应用开发-多进程程序设计 一 创建进程 fork和vfork的区别 1 fork创建的子进程有自己的数据段和堆栈而vfork创建的子进程跟父进程共享数据段 二 进程退出 父进程能使用return 0和exit(0)而子进程只能使用exit(0) 三 execl和fork的区别 execl不创建子进程,而是覆盖后面的代码段 fork创建子进程,不覆盖代码段 四 相应的函数 1 创建进程 函数名   fork 函数原形 pid_t fork(void) 函数功能 创建一个子进程 所属头文件

jplogic 快速开发平台开发案例其一

jplogic v1.0开发陆续更新,意在和广大网友分享交流,通过寻求合作伙伴,交流群376447127.下面是jplogic的关于知识库模块的部分功能,如下进行功能展示: 知识库主界面: 新增知识类别: 新增文档: 调整类别结构: 附件明细操作: 文档信息查看:(将上传的各种文本文件转化成swf格式,便可以实现仿百度文库在线阅读功能) 海量知识库文档高级检索(数据库检索.索引检索(全文检索))等功能. jplogic 快速开发平台开发案例其一,布布扣,bubuko.com

html5开发手机打电话发短信功能,html5的高级开发,html5开发大全,html手机电话短信功能详解

在很多的手机网站上,有打电话和发短信的功能,对于这些功能是如何实现的呢.其实不难,今天我们就用html5来实现他们.简单的让你大开眼界. HTML5 很容易写,但创建网页时,您经常需要重复做同样的任务,如创建表单.在这...有 HTML5 启动模板.空白图片.打电话和发短信.自动完成等等,帮助你提高开发效率的同时,还带来了更炫的功能.好了,我们今天就来做一做看看效果吧!! 看代码: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitio

IOS开发创建开发证书及发布App应用(二)——创建证书

源于:http://www.jkqnb.com/ydkf/article/27 预览图 2. 创建证书 证书分为两种, 一种是开发者证书,主要是用来真机调试的 另一种就是发布证书,就是用来发布应用的, 最好是两种都要下载,不然编译时候可能报错,我猜想可能苹果怕你没用真机调试 创建证书分为两个步骤: 在苹果电脑生成证书签名公钥 提交证书公钥文件到开发者网站 1)  创建开发者证书  1.生成证书签名公钥 在有Mac OS X的操作系统中打开"应用程序" -- "实用工具&quo

web开发原生开发混合开发的区别优势

最近有人在讨论是原生开发好还是,混合开发好,以下是引用了数据来说: 最近原生应用.Web应用.混合应用的名字让我们听得比较熟悉了,现在我们就通过评析各种应用的优缺点来更进一步看看这三者的区别. 一.原生应用 你使用过微软PowerPoint或者Word吧?这些可直接在你电脑上运行或者在智能手机上运行,简单来说,原生应用是特别为某种操作系统开发的,比如iOS.Android.黑莓等等,它们是在各自的移动设备上运行的. 优点: 可访问手机所有功能(GPS.摄像头): 速度更快.性能高.整体用户体验不

IOS开发创建开发证书及发布App应用(一)——流程说明

源于:http://www.jkqnb.com/ydkf/article/26 描述 先说一下这个发布 编译 苹果app的流程吧1. 注册苹果开发者帐号2. 创建证书 3. 创建App ID(不是那个登录账号)4. 创建配置概要文件5. 应用编译6. 应用打包 7. 在iTunes创建填写应用基本信息8. 使用Application Loader工具上传应用9. 等待审核 1.注册苹果开发者账号注册之后一定要成为付费会员,一种99美元(标准版) 一种299美元(企业版)具体区别就百度吧,一般都是

Android 开发之开发插件使用:Eclipse 插件 SQLiteManger eclipse中查看数据内容--翻译

最近研究了一段时间Android开发后发现,google自带的ADT工具,缺失一些开发常用的东西,希望可以构建一个类似使用JAVA EE开发体系一样开发的工具包集合,包括前台开发,调试,到后台数据库的管理,到此,在网上逛了一遍发现这个一些常用的插件功能很强大,所以我决定做一系列翻译这些插件安装使用的教程,希望大家喜欢. 本文受益于这篇文章,所以决定翻译这篇文章中的一部分东西工具.19 个 Android 开发工具投递人 itwriter 发布于 2014-05-08 09:32 本文翻译:Ecl

SDP软件快速开发平台 ---- 开发平台详细介绍

一.前言   在企业间的商业竞争越来越激烈的今天,如何快速实现客户需求,如何快速便捷的开发.修改.更新.维护软件项目系统功能,如何降低软件研发的成本,如何降低公司人员流动对软件开发项目造成的影响.如何提高团队开发效率.如何降低开发人员的技术水平要求.如何缩短开发周期.如何同时开发多个项目等等,在此目标基础上我公司研发了软件快速开发平台(Software Rapid Development Platform)工具,简称SDP.通过软件快速平台能快速便捷的设计开发生成B/S架构 html项目软件.