【夯实PHP基础】PHP多进程-- pcntl_fork实现

本文地址php

参考文档html

点击关注 微信公众号,更多 干货文章等你~

 

分享提纲:linux

  1. 概述算法

  2.安装(只支持Linux)ubuntu

  3. 代码实验多进程pcntl_fork数组

  4. 具体解释bash

 

 

1. 概述

PHP有个pcntl_fork的函数能够实现多进程,但要加载pcntl拓展,并且只有在linux下才能编译这个拓展,有时间在ubuntu下玩了下。微信

 

2. 安装(只支持Linux)

    2.1) 首先在ubuntu下编译pcntl.so,个人ubuntu下找不到pcntl的包,因而函数

建立一个文件夹下载了整个PHP包,在里面找到了pcntl包运行以下命令post

 
# mkdir php
# cd php
# apt-get source php5
# cd php5-(WHATEVER_RELEASE)/ext/pcntl
# phpize
# ./configure (注一)
# make
# make install 

 

phpize 命令是用来准备 PHP 外挂模块的编译环境的。 

 

成功的安装将创建 extname.so 并放置于 PHP 的外挂模块目录中 (预设存放于 /usr/lib/php/modules/ 内) 。
须要调整 php.ini,加入 extension=extname.so 这一行以后才能使用此外挂模块。 

 

  3. 代码实验多进程 pcntl_fork

 

 1 <?php  
 2 //测试php的多进程
 3 
 4     while(1)//循环采用3个进程
 5     {/*{{{*/
 6         //declare(ticks=1);
 7         $bWaitFlag= FALSE; // 是否等待进程结束
 8         //$bWaitFlag = TRUE; // 是否等待进程结束
 9         $intNum= 3; // 进程总数
10         $pids= array(); // 进程PID数组
11         for($i= 0; $i<$intNum; $i++)
12         {
13             $pids[$i] = pcntl_fork();// 产生子进程,并且从当前行之下开试运行代码,并且不继承父进程的数据信息
14             /*if($pids[$i])//父进程
15             {
16 //echo $pids[$i]."parent"."$i -> " . time(). "\n";
17             }
18             */
19              if($pids[$i] == -1)
20              {
21                 echo"couldn't fork". "\n";
22              }
23              elseif(!$pids[$i])
24              {
25                  sleep(1);
26                  echo"\n"."第".$i."个进程 -> ". time(). "\n";
27                 //$url=" 抓取页面的例子
28                 //$content = file_get_contents($url);
29                 //file_put_contents('message.txt',$content);
30                 //echo "\n"."第".$i."个进程 -> " ."抓取页面".$i."-> " . time()."\n";
31                  exit(0);//子进程要exit不然会进行递归多进程,父进程不要exit不然终止多进程
32              }
33             if($bWaitFlag)
34             {
35                 pcntl_waitpid($pids[$i], $status, WUNTRACED);echo"wait $i -> ". time() . "\n";
36             }        
37         }
38         sleep(1);
39 }/*}}}*/

 

 

保存为fork.php 在命令行运行 php fork.php

运行结果:

 

 

4. 具体解释

pcntl函数还有一些功能没实验,例如进程状态,根据相应状态进行一些处理,运用多进程能够增长处理数据的效

率。在网上看到的fork的解释:

fork以后,操做系统会复制一个与父进程彻底相同的子进程,虽然说是父子关系,可是在操做系统看来,他们更像兄弟关系,这2个进程共享代码空间,但 是数据空间是互相独立的,子进程数据空间中的内容是父进程的完整拷贝,指令指针也彻底相同,但只有一点不一样,若是fork成功,子进程中fork的返回值 是0,父进程中fork的返回值是子进程的进程号,若是fork不成功,父进程会返回错误。
能够这样想象,2个进程一直同时运行,并且步调一致,在fork以后,他们分别做不一样的工做,也就是分岔了。这也是fork为何叫fork的缘由。
至于那一个最早运行,可能与操做系统有关,并且这个问题在实际应用中并不重要,若是须要父子进程协同,能够经过原语的办法解决。

----------------------------------------------

fork前父进程的东西子进程能够继承,而在fork后子进程没有任何和父进程的继承关系了。在子进程里建立的东西是子进程的,在父进程建立的东西是父进程的。能够彻底当作两个进程。

----------------------------------------------

在程序段里用了fork();以后程序出了分岔,派生出了两个进程。具体哪一个先运行就看该系统的调度算法了。
在这里,咱们能够这么认为,在运行到”pid=fork();”时系统派生出一个跟主程序如出一辙的子进程。该进程的”pid=fork();”一句中 pid获得的就是子进程自己的pid;子进程结束后,父进程的”pid=fork();”中pid获得的就是父进程自己的pid。所以改程序有两行输出。

----------------------------------------------

fork()函数复制了当前进程的PCB,并向父进程返回了派生子进程的pid。并且根据上面”corand”兄的提示,父子进程并行,打印语句的 前后彻底看系统的调度算法。打印的内容控制则靠pid变量来控制。由于咱们知道fork()向父进程返回了派生子进程的pid,是个正整数;而派生子进程 的pid变量并无被改变。这一区别使得咱们看到了他们的不一样输出。

----------------------------------------------

1,派生子进程的进程,即父进程,其pid不变;2,对子进程来讲,fork返回给它0,但它的pid绝对不会是0;之因此fork返回0给它,是由于它随时能够调用getpid()来获取本身的pid;3,fork以后父子进程除非采用了同步手段,不然不能肯定谁先运行,也不能肯定谁先结束。认为子进程结束后父进程才从fork返回的,这是不对的,fork不是这样的,vfork才这样。

相关文章
相关标签/搜索