php 进程函数,php多进程函数
在服务器跑脚本时,避免不了一些耗时任务,使用多进程是必不可少的。而在 PHP5.5 之后,PHP 开始加入了多进程元素,以满足开发需求。
推荐课程:PHP教程。
php多进程一般应用在php_cli命令行中执行php脚本,实现多进程需要开启的扩展:pcntl、 posix(pcntl是process control进程管理的缩写)。Windows 环境下不支持 PHP 的多进程编程,本文主要在 Linux 环境下开发测试
pcntl_fork — 在当前进程当前位置产生分支(子进程)。
一个fork子进程的基础示例:$pid = pcntl_fork();
//父进程和子进程都会执行下面代码
if ($pid == -1) {
//错误处理:创建子进程失败时返回-1.
die('could not fork');
} else if ($pid) {
//父进程会得到子进程号,所以这里是父进程执行的逻辑
pcntl_wait($status); //等待子进程中断,防止子进程成为僵尸进程。
} else {
//子进程得到的$pid为0, 所以这里是子进程执行的逻辑。
}
如果一个任务被分解成多个进程执行,就会减少整体的耗时。
比如有一个比较大的数据文件要处理,这个文件由很多行组成。如果单进程执行要处理的任务,量很大时要耗时比较久。这时可以考虑多进程。
来看一道面试题,有一个1000万个元素的int数组,需要求和,平均分到4个进程处理,每个进程处理一部分,再将结果统计出来,代码如下<?php
$arrint = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];//假设很多
$arrint = array_chunk($arrint,4,TRUE);
for ($i = 0; $i < 4; $i ){
$pid = pcntl_fork();
if ($pid == -1) {
die("could not fork");
} elseif ($pid) {
echo $pid;
echo "I'm the Parent $i\n";
} else {
// 子进程处理
// $content = file_get_contents("prefix_name0".$i);
$psum = array_sum($arrint[$i]);
echo $psum . "\n";分别输出子进程的部分求和数字,但是无法进行想加,因为进程互相独立
exit;// 一定要注意退出子进程,否则pcntl_fork() 会被子进程再fork,带来处理上的影响。
}
}
// 等待子进程执行结
while (pcntl_waitpid(0, $status) != -1) {
$status = pcntl_wexitstatus($status);
echo "Child $status completed\n";
}
上诉答案中,是把数组分为4个子数组分别用4个子进程去处理了,但是没有办法把所计算的结果相加,因为进程都是独立完成任务的,没有办法共享同一个(内存)变量,下面将引进消息队列来解决进程通信的问题<?php
$arrint = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];//假设很多
$arrint = array_chunk($arrint,4,TRUE);//把数组分为4个
// 创建消息队列,以及定义消息类型(类似于数据库中的库)
$id = ftok(__FILE__,'m');//生成文件key,唯一
$msgQueue = msg_get_queue($id);
const MSG_TYPE = 1;
msg_send($msgQueue,MSG_TYPE,'0');//给消息队列一个默认值0,必须是字符串类型
//fork出四个子进程
for ($i = 0; $i < 4; $i ){
$pid = pcntl_fork();
if ($pid == -1) {
die("could not fork");
} elseif ($pid) {
echo $pid;
echo "I'm the Parent $i\n";
} else {
// 子进程处理逻辑,相互独立,解决办法,放到内存消息队列中
$part = array_sum($arrint[$i]);
implode_sum($part);//合成计算出的sum
exit;// 一定要注意退出子进程,否则pcntl_fork() 会被子进程再fork,带来处理上的影响。
}
}
function implode_sum($part){
global $msgQueue;
msg_receive($msgQueue,MSG_TYPE,$msgType,1024,$sum);//获取消息队列中的值,最后一个参数为队列中的值
$sum = intval($sum) $part;
msg_send($msgQueue,MSG_TYPE,$sum);//发送每次计算的结果给消息队列
}
// 等待子进程执行结束
while (pcntl_waitpid(0, $status) != -1) {
$status = pcntl_wexitstatus($status);
$pid = posix_getpid();
echo "Child $status completed\n";
}
//所有子进程结束后,再取出最后在队列中的值,就是int数组的和
msg_receive($msgQueue,MSG_TYPE,$msgType,1024,$sum);
echo $sum;//输出120
php 进程函数,php多进程函数相关推荐
- 使用进程池模拟多进程爬取url获取数据,使用进程绑定的回调函数去处理数据...
1 # 使用requests请求网页,爬取网页的内容 2 3 # 模拟使用进程池模拟多进程爬取网页获取数据,使用进程绑定的回调函数去处理数据 4 5 import requests 6 from mu ...
- python并发处理list数据_python并发编程之多进程2--------数据共享及进程池和回调函数...
一.数据共享 1.进程间的通信应该尽量避免共享数据的方式 2.进程间的数据是独立的,可以借助队列或管道实现通信,二者都是基于消息传递的. 虽然进程间数据独立,但可以用过Manager实现数据共享,事实 ...
- Python之路 34:并发与并行、锁(GIL、同步锁、死锁与递归锁)、信号量、线程队列、生消模型、进程(基础使用、进程通信、进程池、回调函数)、协程
内容: 同步锁 死锁.递归锁 信号量和同步对象(暂时了解即可) 队列------生产者和消费者模型 进程(基础使用.进程通信.进程池.回调函数) 协程 一.并发并行与同步异步的概念 1.1.并发和并行 ...
- 进程间的数据共享、进程池的回调函数和线程初识、守护线程
一.进程的数据共享 进程间数据是独立的,可以借助于队列或管道实现通信,二者都是基于消息传递的 虽然进程间数据独立,但可以通过Manager实现数据共享.把所有实现了数据共享的比较便捷的类都重新又封装了 ...
- 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 一 | mmap 函数简介 )
文章目录 一.mmap 简介 二.mmap 函数作用 一.mmap 简介 mmap 函数的作用是 将 文件 映射到 内存中 , 映射的单位必须是 PAGE_SIZE ; mmap 函数引入头文件 : ...
- linux exec 二程序,二十五、Linux 进程与信号---exec函数
25.1 介绍 在用 fork 函数创建子进程后,子进程往往要调用一种 exec 函数以执行另一个程序 当进程调用一种 exec 函数时,该进程完全由新程序代换,替换原有进程的正文,而新程序则从其 m ...
- 进程线程005 SwapContext函数分析
文章目录 线程切换与TSS 内核堆栈 内核堆栈结构 调用API进零环 SwapContext代码分析 线程切换与FS SwapContext代码分析 SwapContext的其他问题 SwapCont ...
- 4进程原语:fork()函数,getpid()函数和getppid()函数,getuid()函数,getgid()函数,vfork()
1fork()函数 子进程复制父进程的0到3g空间和父进程内核中的PCB,但id号不同.fork调用一次返回两次,有以下特点: A:父进程中返回子进程ID B:子进程中返回0 C:读时共享,写时 ...
- UNIX环境编程学习笔记(19)——进程管理之fork 函数的深入学习
在"进程控制三部曲"中,我们学习到了 fork 是三部曲的第一部,用于创建一个新进程.但是关于 fork 的更深入的一些的东西我们还没有涉及到,例如,fork 创建的新进程与调用进 ...
最新文章
- Java改知能机_Java 面试突击之 Java 并发知识基础 进阶考点全解析
- 序列联配(alignment)和数据库搜索方法简介
- python中常用的推导(字典推导和列表推导)
- 一个设计元素很多的网站
- 疫情加速中国服务器采购 数字化转型成为增长“新引擎”
- java 快速排序算法简单_排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序......
- [梦]2005年9月1日
- 环评图件制作-数据处理+图件制作(weixin公众号【图说GIS】)
- 个体营业执照与公司营业执照的区别
- 计算机操作系统锁定如何解锁,笔记本键盘锁定,小编教你笔记本键盘锁定怎么解锁...
- Error: Unresolved node modules: vue
- Excel合并表格之vba
- 图像拼接(八):拼接多幅图像+Matlab实现+Stanford Open Course
- VB 生成0~1的随机小数(不包含1),再用VB,感慨万千
- python学习笔记全过程_Python学习过程笔记整理(四)
- 电话号码归属地批量查询软件选择需谨慎
- Vue3+ElementPlus 表格分页组件封装
- leetcode13——步长k的差值小于t的元素组,包含1的正方形面积,完全二叉树的结点个数,矩形重叠面积,汇总区间
- 三万块钱6天的区块链培训,我学会了搭建区块链系统框架?
- linux ntp时间立即同步命令_Linux系统时间同步方法小结
热门文章
- 【数据结构总结】第八章 排序
- linux安装指定mysql版本安装,linux yum安装指定版本mysql
- portainer 启动mysql_Docker管理工具Portainer
- logrotate测试_使用 logrotate 对 apache/nginx 日志切割
- Java黑皮书课后题第7章:*7.21(整数求和)编写程序,从命令行输入不定数目的整数,然后显示它们的和
- Java黑皮书课后题第3章:*3.3(代数:求解2*2线性方程)编写程序,提示用户输入a、b、c、d、e和f,然后显示结果
- oracle resetlogs 误删,oracle undo表空间误删恢复
- Java Decimal范围_Java BigDecimal初探
- 列表数据提交_Mybatis-实现数据的增删改查
- vue为p标签_通过vue.js几个基本操作,理解一下什么是插槽「606」