设为首页 收藏本站
查看: 768|回复: 0

[经验分享] pcntl_fork安装以及实现PHP多进程

[复制链接]

尚未签到

发表于 2015-8-29 13:32:27 | 显示全部楼层 |阅读模式
  PHP有个pcntl_fork的函数可以实现多进程,但要加载pcntl拓展,而且只有在linux下才能编译这个拓展,有时间在ubuntu下玩了下。
  1.首先在ubuntu下编译pcntl.so,我的ubuntu下找不到pcntl的包,于是
  创建一个文件夹下载了整个PHP包,在里面找到了pcntl包运行如下命令






# 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 这一行之后才能使用此外挂模块。
  
  2,开始实验pcntl_fork



01<?php

02//while(1)//循环采用3个进程

03//{

04//declare(ticks=1);

05$bWaitFlag = FALSE; // 是否等待进程结束

06//$bWaitFlag = TRUE; // 是否等待进程结束

07$intNum = 3; // 进程总数

08$pids = array(); // 进程PID数组

09for($i = 0; $i <$intNum; $i++)

10{$pids[$i] = pcntl_fork();// 产生子进程,而且从当前行之下开试运行代码,而且不继承父进程的数据信息

11/*if($pids[$i])//父进程

12{

13//echo $pids[$i]."parent"."$i -> " . time(). "\n";

14}

15*/

16if($pids[$i] == -1)

17{

18echo "couldn't fork". "\n";

19}

20elseif(!$pids[$i])

21{

22sleep(1);

23echo "\n"."第".$i."个进程 -> " . time(). "\n";

24//$url=" http://xxx/comments.php?p=".$i;//抓取页面的例子

25//$content = file_get_contents($url);

26//file_put_contents('message.txt',$content);

27//echo "\n"."第".$i."个进程 -> " ."抓取页面".$i."-> " . time()."\n";

28exit(0);//子进程要exit否则会进行递归多进程,父进程不要exit否则终止多进程

29}

30if ($bWaitFlag)

31{

32pcntl_waitpid($pids[$i], $status, WUNTRACED);echo "wait $i -> " . time() ."\n";}}

33//sleep(1);

34//}

35?>
  保存为fork.php 在命令行运行 php fork.php

  pcntl函数还有一些功能没实验,例如进程状态,根据相应状态进行一些处理,运用多进程可以增加处理数据的效
  率。在网上看到的fork的解释:
  fork之后,操作系统会复制一个与父进程完全相同的子进程,虽说是父子关系,但是在操作系统看来,他们更像兄弟关系,这2个进程共享代码空间,但 是数据空间是互相独立的,子进程数据空间中的内容是父进程的完整拷贝,指令指针也完全相同,但只有一点不同,如果fork成功,子进程中fork的返回值 是0,父进程中fork的返回值是子进程的进程号,如果fork不成功,父进程会返回错误。
可以这样想象,2个进程一直同时运行,而且步调一致,在fork之后,他们分别作不同的工作,也就是分岔了。这也是fork为什么叫fork的原因。
至于那一个最先运行,可能与操作系统有关,而且这个问题在实际应用中并不重要,如果需要父子进程协同,可以通过原语的办法解决。
  ----------------------------------------------
  fork前父进程的东西子进程可以继承,而在fork后子进程没有任何和父进程的继承关系了。在子进程里创建的东西是子进程的,在父进程创建的东西是父进程的。可以完全看成两个进程。
  ----------------------------------------------
  在程序段里用了fork();之后程序出了分岔,派生出了两个进程。具体哪个先运行就看该系统的调度算法了。
在这里,我们可以这么认为,在运行到&#8221;pid=fork();&#8221;时系统派生出一个跟主程序一模一样的子进程。该进程的&#8221;pid=fork();&#8221;一句中 pid得到的就是子进程本身的pid;子进程结束后,父进程的&#8221;pid=fork();&#8221;中pid得到的就是父进程本身的pid。因此改程序有两行输出。
  ----------------------------------------------
  fork()函数复制了当前进程的PCB,并向父进程返回了派生子进程的pid。而且根据上面&#8221;corand&#8221;兄的提示,父子进程并行,打印语句的 先后完全看系统的调度算法。打印的内容控制则靠pid变量来控制。因为我们知道fork()向父进程返回了派生子进程的pid,是个正整数;而派生子进程 的pid变量并没有被改变。这一区别使得我们看到了他们的不同输出。
  ----------------------------------------------
  1,派生子进程的进程,即父进程,其pid不变;
2,对子进程来说,fork返回给它0,但它的pid绝对不会是0;之所以fork返回0给它,是因为它随时可以调用getpid()来获取自己的pid;
3,fork之后父子进程除非采用了同步手段,否则不能确定谁先运行,也不能确定谁先结束。认为子进程结束后父进程才从fork返回的,这是不对的,fork不是这样的,vfork才这样。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-105980-1-1.html 上篇帖子: PHP 拷贝图像 imagecopy 与 imagecopyresized 函数 下篇帖子: Eclipse php快捷键大全
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表