【原文地址:https://blog.ti-node.com/blog...】其实PHP是多线程的,只是很多人不会不要经常使用它。要使用PHP的多线程,首先需要下载并安装一个线程安全版(ZTS版)的PHP,然后安装pecl的pthread扩展。其实PHP是有多个进程的,又有人用了。总的来说,PHP的多进程还不错。你只需要在安装PHP的时候打开pcntl模块(是不是有点像UNIX中的fcntl.....)就可以了。在*NIX下,在终端命令行使用php-m查看pcntl模块是否启用。所以我们只说php的多进程,php的多线程暂时搁置一边。注意:不要在apache或fpm环境下使用php多进程,这样会产生不可预知的后果。进程是程序执行的一个实例。例如,有一个名为“virus.exe”的程序。这个程序通常以文件的形式存储在硬盘上。当你双击运行它时,就会形成一个程序的进程。系统会为每个进程分配一个唯一的非负整数来标记进程。这个数字称为进程ID。当进程被杀死或终止时,其进程ID将被系统回收,然后分配给新的剩余进程。说了这么多,这该死的东西有什么用?我一般都是用CI和YII写一个CURD和这个没关系。其实如果你了解APACHEPHPMOD或者FPM,你就会知道这些东西都是通过多进程实现的。以FPM为例,nginx一般作为http服务器处于最前端,nginx自己处理静态文件请求,将php动态请求转发给php-fpm进程处理。如果你的php-fpm配置只开启5个进程,如果处理任意一个用户的请求需要1秒,那么5个fpm进程1秒最多只能处理5个用户请求。所以结论是:如果你想在单位时间内工作得更快、更多,你需要更多的进程。总之,多进程可以加快任务处理速度。在php中,我们使用pcntl_fork()来创建多个进程(在*NIX系统的C语言编程中,已有的进程通过调用fork函数生成一个新的进程)。fork后的新进程成为子进程,原进程成为父进程,子进程有父进程的副本。这里注意:子进程和父进程共享程序文本域。子进程拥有父进程的数据空间和堆、栈的副本。注意是拷贝,不是共享父进程,子进程会继续执行fork后的程序代码。fork之后就是父进程了。进程先执行还是子进程先执行无法确定,这取决于系统调度(取决于信念)。这里说的是子进程拥有父进程的数据空间和堆、栈的副本。事实上,在大多数实现中并非如此。精确副本。它们大多采用COW(CopyOnWrite)技术来节省存储空间。简单的说,如果父进程和子进程不修改数据、堆和栈,那么父进程和子进程暂时共享同一个数据、堆和栈。只有当父进程或子进程试图修改数据、堆和栈时,才会发生复制操作,称为写时复制。调用pcntl_fork()后,该函数返回两个值。返回子进程在父进程中的进程ID,或者子进程内部的数字0本身。由于多进程在apache或fpm环境下无法正常运行,所以必须在phpcli环境下执行以下php代码。第一段代码,先解释一下,程序从pcntl_fork()开始后,父进程和子进程会继续执行代码:0){echo"我是父亲".PHP_EOL;}elseif(0==$pid){echo"我是儿子".PHP_EOL;}else{echo"forkfailed".PHP_EOL;}将文件保存为test.php,然后使用cli执行,结果如下图:第二段代码用来说明子进程有一份父进程的数据,而不是共享:0){$number+=1;echo"我是父亲,number+1:{$number}".PHP_EOL;}elseif(0==$pid){$number+=2;echo"我是父亲,number+2:{$number}".PHP_EOL;}else{echo"forkfailed".PHP_EOL;}第三段代码比较容易让人迷惑,pcntl_fork()配合for循环做一些事情,问题来了:“Son”会显示多少次?0){//什么都不做...}elseif(0==$pid){echo"son".PHP_EOL;}}上面代码的执行结果如下:仔细一算,原来“儿子”显示了7次。奇怪了,不是3次吗?...下面我修改一下代码,结合下面的代码,想想为什么是7次,而不是3次。0){//什么都不做...}elseif(0==$pid){echo"son".PHP_EOL;出口;}}执行结果如下图所示:前面强调过:fork后父进程和子进程会继续执行程序代码。我不会在这里解释。如果实在看不懂,可以自己画画想想。为了避免写出一篇臭理论文章,这里强行拆散。下一章会讲僵尸进程和孤儿进程的一些恩怨。
