pcntl扩展学习笔记一(pcntl_fork与pcntl_wait,串行执行分析)
2017-04-06 00:00
411 查看
对编程的理解,应该到深入到操作系统级别。进程控制,我一直都没有接触,感觉好高端,今天啃了一下pcntl扩展的最简单的两个函数,有点心得,记录一下吧,欢迎抛砖。
新建代码文件 pcntl_wait.php,如下:
php -f pcntl_wait.php 运行结果如下:
为何是如上运行过程?
参考了PHP手册和网友blog以上代码能够循环产生子进程,并且父进程会阻塞等待子进程退出,这样就产生了一个问题,父进程必须等待一个子进程退出后,再创建另外一个
个人分析如下:
1.运行shell命令(该进程ID是3471),生成主进程PID为6498
开始循环i=0
6498 此时的父进程
|fork
6499 父进程(6498阻塞),该子进程(6499)执行 ,输出:child cid:0 myid:6499 pid:6499 ppid:6498 i:0 1491394182.2065
然后i++ i=1,再次循环
继续循环i=1
6499 此时的父进程
|fork
6500 父进程(6499阻塞),该子进程(6500)执行,输出:child cid:0 myid:6500 pid:6500 ppid:6499 i:1 1491394182.2077
然后i++ i=2,本次循环终止,回到其主进程6499
6499 解除阻塞,
此时i=1(因为阻塞时i=1),继续执行 输出:parent cid:6500 myid:6499 pid:6499 ppid:6498 i:1 1491394182.2143
然后i++ i=2,本次循环终止,回到其主进程6498
6498 解除阻塞,
此时i=0(因为阻塞时i=0),继续执行,输出:parent cid:6499 myid:6498 pid:6498 ppid:3471 i:0 1491394182.2211
然后i++ i=1,再次循环
继续循环i=1
6498 此时的父进程
|fork
6501 父进程(6498阻塞),该子进程(6501)执行,输出:child cid:0 myid:6501 pid:6501 ppid:6498 i:1 1491394182.222
然后i++ i=2,本次循环终止,回到其主进程6498
6498 解除阻塞
此时i=1(因为阻塞时为i=1),继续执行,输出:parent cid:6501 myid:6498 pid:6498 ppid:3471 i:1 1491394182.2302
然后i++ i=2,本次循环终止,回到其主进程3471,最后命令结束。
新建代码文件 pcntl_wait.php,如下:
$i = 0; while($i < 2) { $pid = pcntl_fork(); // 父进程和子进程都会执行以下代码 if ($pid == -1) { // 创建子进程错误,返回-1 die('could not fork'); } else if ($pid) { // 父进程会得到子进程号,所以这里是父进程执行的逻辑 pcntl_wait($status); // 父进程必须等待一个子进程退出后,再创建下一个子进程。 $cid = $pid; // 子进程的ID $pid = posix_getpid(); // pid 与mypid一样,是当前进程Id $myid = getmypid(); $ppid = posix_getppid(); // 进程的父级ID $time = microtime(true); echo "I am parent cid:$cid myid:$myid pid:$pid ppid:$ppid i:$i $time \n"; } else { // 子进程得到的$pid 为0,所以这里是子进程的逻辑 $cid = $pid; $pid = posix_getpid(); $ppid = posix_getppid(); $myid = getmypid(); $time = microtime(true); echo "I am child cid:$cid myid:$myid pid:$pid ppid:$ppid i:$i $time \n"; //exit; //sleep(2); } $i++; }
php -f pcntl_wait.php 运行结果如下:
I am child cid:0 myid:6499 pid:6499 ppid:6498 i:0 1491394182.2065 I am child cid:0 myid:6500 pid:6500 ppid:6499 i:1 1491394182.2077 I am parent cid:6500 myid:6499 pid:6499 ppid:6498 i:1 1491394182.2143 I am parent cid:6499 myid:6498 pid:6498 ppid:3471 i:0 1491394182.2211 I am child cid:0 myid:6501 pid:6501 ppid:6498 i:1 1491394182.222 I am parent cid:6501 myid:6498 pid:6498 ppid:3471 i:1 1491394182.2302
为何是如上运行过程?
参考了PHP手册和网友blog以上代码能够循环产生子进程,并且父进程会阻塞等待子进程退出,这样就产生了一个问题,父进程必须等待一个子进程退出后,再创建另外一个
个人分析如下:
1.运行shell命令(该进程ID是3471),生成主进程PID为6498
开始循环i=0
6498 此时的父进程
|fork
6499 父进程(6498阻塞),该子进程(6499)执行 ,输出:child cid:0 myid:6499 pid:6499 ppid:6498 i:0 1491394182.2065
然后i++ i=1,再次循环
继续循环i=1
6499 此时的父进程
|fork
6500 父进程(6499阻塞),该子进程(6500)执行,输出:child cid:0 myid:6500 pid:6500 ppid:6499 i:1 1491394182.2077
然后i++ i=2,本次循环终止,回到其主进程6499
6499 解除阻塞,
此时i=1(因为阻塞时i=1),继续执行 输出:parent cid:6500 myid:6499 pid:6499 ppid:6498 i:1 1491394182.2143
然后i++ i=2,本次循环终止,回到其主进程6498
6498 解除阻塞,
此时i=0(因为阻塞时i=0),继续执行,输出:parent cid:6499 myid:6498 pid:6498 ppid:3471 i:0 1491394182.2211
然后i++ i=1,再次循环
继续循环i=1
6498 此时的父进程
|fork
6501 父进程(6498阻塞),该子进程(6501)执行,输出:child cid:0 myid:6501 pid:6501 ppid:6498 i:1 1491394182.222
然后i++ i=2,本次循环终止,回到其主进程6498
6498 解除阻塞
此时i=1(因为阻塞时为i=1),继续执行,输出:parent cid:6501 myid:6498 pid:6498 ppid:3471 i:1 1491394182.2302
然后i++ i=2,本次循环终止,回到其主进程3471,最后命令结束。
相关文章推荐
- iOS学习笔记28-JS执行过程分析
- MyBatis源码学习笔记(十)SQL执行流程分析
- Linux netfilter 学习笔记 之二 ip 层netfilter的hook 注册以及执行hook函数的概要分析
- Linux netfilter 学习笔记 之二 ip 层netfilter的hook 注册以及执行hook函数的概要分析
- Arm汇编学习笔记(二)——编写编译并执行依赖外部模块的汇编代码以及PIC代码分析
- Linux内核分析第七周学习笔记——Linux内核如何装载和启动一个可执行程序
- JS学习笔记 – 分析 JavaScript的执行顺序
- PCNTL--PHP进程控制扩展学习笔记
- ASP.NET MVC5学习笔记之Controller同步执行架构分析
- 执行数据库命令Command对象——ADO.NET学习&应用笔记之三
- Asp.Net Ajax 学习笔记16 Profile Service扩展方式
- Asp.Net Ajax 学习笔记10 JavaScript的原生类型以及Microsoft AJAX Library的相关扩展(下)
- Lua学习笔记五--真正的入门:编写Lua扩展库
- Asp.Net Ajax 学习笔记18 Authentication Service的实现方式与扩展
- ASP.NET控件开发学习笔记--第8回 WebControl分析
- pb学习笔记之三 仓库信息管理系统分析
- MonoRail学习笔记四:MonoRail基本流程分析
- [导入]面向对象学习笔记四--需求分析的阶段划分
- C#学习笔记(七):接口的执行
- Asp.Net Ajax 学习笔记9 JavaScript的原生类型以及Microsoft AJAX Library的相关扩展(上)