PHP多进程---fork多个子进程,父进程阻塞与非阻塞
PHP的多进程是不是可以无限制的fork子进程?
fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
在父进程中,fork返回新创建子进程的进程ID
在子进程中,fork返回0
如果出现错误,fork返回一个负值
在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个子进程,一个父进程。在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID。我们可以通过fork返回的值来判断当前进程是子进程还是父进程。
引用一位网友的话来解释fpid的值为什么在父子进程中不同。“其实就相当于链表,进程形成了链表,父进程的fpid(p 意味point)指向子进程的进程id, 因为子进程没有子进程,所以其fpid为0
<?php //定义进程数量 define('FORK_NUMS', 5); //用于保存进程pid $pids = array(); //我们创建5个子进程 for ($i = 0; $i < FORK_NUMS; $i++) { $pids[$i] = pcntl_fork(); if ( $pids[$i] == -1 ) { die('fork error'); } else if ( $pids[$i] ) { //这里是父进程空间,也就是主进程 //我们的for循环第一次进入到这里时,pcntl_wait会挂起当前主进程,等待第一个子进程执行完毕退出 //注意for循环的代码是在主进程的,挂起主进程,相当于当前的for循环也阻塞在这里了 //第一个子进程退出后,然后再创建第二个子进程,到这里后又挂起,等待第二个子进程退出,继续创建第三个,等等。。 pcntl_wait($status); } else { //这里是子进程空间 echo "父进程ID: ", posix_getppid(), " 进程ID : ", posix_getpid(), " {$i} \r\n"; //我们让子进程等待3秒,再退出 sleep(3); exit; } }
阻塞与非阻塞案例
通过pcntl_fork来创建子进程,使用pcntl_wait和pcntl_waitpid来回收子进程。子进程退出后,父进程没有及时回收,就会产生僵尸进程。
[阻塞案例]
<?php define('FORK_NUMS', 5); $pids = array(); //创建5个子进程 for($i = 0; $i < FORK_NUMS; ++$i) { $pids[$i] = pcntl_fork(); if($pids[$i] == -1) { die('fork error'); } else if ($pids[$i]) { pcntl_wait($status); } else { echo getmypid() , " {$i} \r\n"; exit; } }
执行结果:
# php fork.php 52470 0 52471 1 52472 2 52473 3 52474 4
以上代码通过for循环fork出5个子进场,父进程会阻塞着等待子进程退出,然后创建下一个子进程。
----------Bug: 创建多进程的目的,就是为了能够并行的处理任务,阻塞的方式并不是我们期待的结果-------
[非阻塞案例]
<?php define('FORK_NUMS', 5); $pids = array(); //创建5个子进程 for($i = 0; $i < FORK_NUMS; ++$i) { $pids[$i] = pcntl_fork(); if($pids[$i] == -1) { die('fork error'); } else if ($pids[$i]) { pcntl_wait($status, WNOHANG); } else { echo getmypid() , " {$i} \r\n"; exit; } }
执行结果:
//反复执行几次,发现没有规律 [root@bogon default]# php fork.php 52645 0 52647 2 52646 1 52648 3 52649 4 [root@bogon default]# php fork.php 52660 0 52663 3 52664 4 52661 1 52662 2 [root@bogon default]# php fork.php 52681 0 52683 2 52685 4 52684 3 52682 1
我们可以通过设置pcntl_wait的第二个参数为WNOHANG来控制进程是否阻塞。该函数可以在没有子进程退出的情况下立刻跳出执行后续代码。
pcntl_wait等同于以pid为-1调用pcntl_waitpid函数。
pcntl_waitpid函数可以等待指定pid的进程。
原文地址:https://www.cnblogs.com/xiangshihua/p/13285107.html
- iBatis.Net(2):基本概念与配置
- ASP.NET Web API中的依赖注入什么是依赖注入ASP.NET Web API依赖解析器使用Unity解析依赖配置依赖解析
- 解决Entity Framework查询匿名对象后的跨域访问的一种方式
- WebSocket在ASP.NET MVC4中的简单实现
- 在ASP.NET MVC中使用Unity进行依赖注入的三种方式第一种方法第二种方法第三种方法
- Unity Container中的几种注册方式与示例1.实例注册2.简单类型注册
- 使用Unity创建依赖注入依赖注入生命周期:注册、解析、销毁 注册解析销毁
- 使用WCF进行跨平台开发之三(JAVA调用WCF服务)1.开发必备2.生成WCF客户端3.开发程序4.结束语
- 使用WCF进行跨平台开发之二(IIS托管WCF服务并使用php平台调用)1.系统必备2.在IIS中托管WCF服务3.使用PHP调用托管在IIS中的WCF服务
- 使用WCF进行跨平台开发之一(WCF的实现、控制台托管与.net平台的调用)1.创建项目结构2.契约的设计3.实现服务4.控制台托管服务5.在.net平台中调用WCF
- 使用GUI工具高效构建你自己的Nuget包丰富包的基础信息添加要包含的文件The end
- 网页结构与表现原则
- CSS3动画功能
- Angular开发者手册重点翻译之指令(一)文本和属性绑定ngAttr属性绑定
- php概述
- php教程
- php环境搭建
- PHP书写格式
- php变量
- php常量
- PHP注释
- php数组
- php字符串 string
- PHP整型 integer
- PHP浮点型 float
- php布尔型
- php数据类型之数组
- php数据类型之对象
- php数据类型之null
- php数据类型之间的转换
- php运算符
- php表达式
- PHP循环控制
- PHP流程控制
- php函数
- php全局变量
- PHP魔术变量
- php命名空间
- php 日期
- PHP包含文件
- php文件
- PHP 文件上传
- php Cookies
- php Sessions
- php email
- php安全email
- php错误处理
- PHP异常处理
- php过滤器
- PHP 高级过滤器
- php json
- php 表单
- PHP MySQL 简介
- PHP 连接 MySQL
- php创建数据库
- php 创建表
- php mysq 插入数据
- PHP MySQL 插入多条数据
- PHP MySQL 预处理语句
- php mysql 读取数据
- php mysql where
- PHP MySQL Order By
- PHP MySQL Update
- PHP MySQL Delete
- php ODBC
- Android 购物车加减功能的实现代码
- Yii框架函数简单用法分析
- PHP读取XML文件的方法实例总结【DOMDocument及simplexml方法】
- 浅析PHP7 的垃圾回收机制
- android BottomSheetDialog新控件解析实现知乎评论列表效果(实例代码)
- Laravel框架实现的上传图片到七牛功能详解
- Flutter沉浸式状态栏/AppBar导航栏/仿咸鱼底部凸起导航栏效果
- Android集成zxing扫码框架功能
- Android 实现抖音小游戏潜艇大挑战的思路详解
- 修改Android Studio 的 Logcat 缓冲区大小操作
- Android自定义View验证码输入框
- PHP生成随机字符串实例代码(字母+数字)
- Laravel框架中缓存的使用方法分析
- android实现搜索功能并将搜索结果保存到SQLite中(实例代码)
- Android实现全局右滑返回