【夯实PHP基础】PHP多进程-- pcntl_fork实现
分享提纲:
1. 概述
2.安装(只支持Linux)
3. 代码实验多进程pcntl_fork
4. 具体解释
1. 概述
PHP有个pcntl_fork的函数可以实现多进程,但要加载pcntl拓展,而且只有在linux下才能编译这个拓展,有时间在ubuntu下玩了下。
2. 安装(只支持Linux)
2.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 这一行之后才能使用此外挂模块。
3. 代码实验多进程 pcntl_fork
<?php
//测试php的多进程 while(1)//循环采用3个进程
{/*{{{*/
//declare(ticks=1);
$bWaitFlag= FALSE; // 是否等待进程结束
//$bWaitFlag = TRUE; // 是否等待进程结束
$intNum= 3; // 进程总数
$pids= array(); // 进程PID数组
for($i= 0; $i<$intNum; $i++)
{
$pids[$i] = pcntl_fork();// 产生子进程,而且从当前行之下开试运行代码,而且不继承父进程的数据信息
/*if($pids[$i])//父进程
{
//echo $pids[$i]."parent"."$i -> " . time(). "\n";
}
*/
if($pids[$i] == -1)
{
echo"couldn't fork". "\n";
}
elseif(!$pids[$i])
{
sleep(1);
echo"\n"."第".$i."个进程 -> ". time(). "\n";
//$url=" 抓取页面的例子
//$content = file_get_contents($url);
//file_put_contents('message.txt',$content);
//echo "\n"."第".$i."个进程 -> " ."抓取页面".$i."-> " . time()."\n";
exit(0);//子进程要exit否则会进行递归多进程,父进程不要exit否则终止多进程
}
if($bWaitFlag)
{
pcntl_waitpid($pids[$i], $status, WUNTRACED);echo"wait $i -> ". time() . "\n";
}
}
sleep(1);
}/*}}}*/
保存为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才这样。
【夯实PHP基础】PHP多进程-- pcntl_fork实现的更多相关文章
- 【夯实Mysql基础】记一次mysql语句的优化过程
1. [事件起因] 今天在做项目的时候,发现提供给客户端的接口时间很慢,达到了2秒多,我第一时间,抓了接口,看了运行的sql,发现就是 2个sql慢,分别占了1秒多. 一个sql是 链接了5个表同时使 ...
- 【夯实Mysql基础】记一次mysql语句的优化过程!
1. [事件起因] 今天在做项目的时候,发现提供给客户端的接口时间很慢,达到了2秒多,我第一时间,抓了接口,看了运行的sql,发现就是 2个sql慢,分别占了1秒多. 一个sql是 链接了5个表同 ...
- 夯实Java基础(十一)——内部类
1.内部类的概念 内部类顾名思义:将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类.对于很多Java初学者来说,内部类学起来真的是一头雾水,根本理解不清楚是个什么东西,包括我自己(我太菜 ...
- 夯实Java基础系列1:Java面向对象三大特性(基础篇)
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 [https://github.com/h2pl/Java-Tutorial](https: ...
- 夯实Java基础系列3:一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!
目录 目录 string基础 Java String 类 创建字符串 StringDemo.java 文件代码: String基本用法 创建String对象的常用方法 String中常用的方法,用法如 ...
- 夯实Java基础系列4:一文了解final关键字的特性、使用方法,以及实现原理
目录 final使用 final变量 final修饰基本数据类型变量和引用 final类 final关键字的知识点 final关键字的最佳实践 final的用法 关于空白final final内存分配 ...
- 夯实Java基础系列5:Java文件和Java包结构
目录 Java中的包概念 包的作用 package 的目录结构 设置 CLASSPATH 系统变量 常用jar包 java软件包的类型 dt.jar rt.jar *.java文件的奥秘 *.Java ...
- 夯实Java基础系列6:一文搞懂抽象类和接口,从基础到面试题,揭秘其本质区别!
目录 抽象类介绍 为什么要用抽象类 一个抽象类小故事 一个抽象类小游戏 接口介绍 接口与类相似点: 接口与类的区别: 接口特性 抽象类和接口的区别 接口的使用: 接口最佳实践:设计模式中的工厂模式 接 ...
- 夯实Java基础系列7:一文读懂Java 代码块和执行顺序
目录 Java中的构造方法 构造方法简介 构造方法实例 例 1 例 2 Java中的几种构造方法详解 普通构造方法 默认构造方法 重载构造方法 java子类构造方法调用父类构造方法 Java中的代码块 ...
随机推荐
- NLP入门(三)词形还原(Lemmatization)
词形还原(Lemmatization)是文本预处理中的重要部分,与词干提取(stemming)很相似. 简单说来,词形还原就是去掉单词的词缀,提取单词的主干部分,通常提取后的单词会是字典中的单 ...
- JS脚本获取URL参数并调用
首先增加一个脚本库,可以是Zepto或者jQuery的,然后获取之后使用switch进行分流处理 <script type="text/javascript" src=&qu ...
- CIL中间语言浅谈
CIL中间语言 通用中间语言(Common Intermediate Language,简称CIL)(曾经被称为微软中间语言或MSIL)是一种属于通用语言架构和.NET框架的低阶(lowest-lev ...
- P9架构师讲解从单机至亿级流量大型网站系统架构的演进过程
阶段一.单机构建网站 网站的初期,我们经常会在单机上跑我们所有的程序和软件.此时我们使用一个容器,如tomcat.jetty.jboos,然后直接使用JSP/servlet技术,或者使用一些开源的框架 ...
- Netty实战五之ByteBuf
网络数据的基本单位总是字节,Java NIO 提供了ByteBuffer作为它的字节容器,但是其过于复杂且繁琐. Netty的ByteBuffer替代品是ByteBuf,一个强大的实现,即解决了JDK ...
- Netty 系列六(编解码器).
一.概念 网络传输的单位是字节,如何将应用程序的数据转换为字节,以及将字节转换为应用程序的数据,就要说到到我们该篇介绍的编码器和解码器. 将应用程序的数据转换为网络格式,以及将网络格式转换为应用程序的 ...
- Java 中变量初始化、子类和父类构造器调用的顺序
先说结论 变量初始化 -> 父类构造器 -> 子类构造器 贴代码 Animcal.java 父类 public class Animal { private static int inde ...
- hive SQL查询结果添加行号
用窗口函数可以解决这个问题: 例:select row_number() over(order by user_id desc) ,tab.* from dws_user_visit_month1 a ...
- C#中try catch finally的执行顺序
1.首先明确一点,就是不管怎样,finally一定会执行,即使程序有异常,并且在catch中thorw 了 ,finally还是会被执行. 2.当try和catch中有return时,finally仍 ...
- 一、Composer下载安装
1.composer下载 英文网站:https://getcomposer.org/ 中文镜像:https://www.phpcomposer.com/ 2.composer安装 • win下安装图文 ...