在服务器跑脚本时,避免不了一些耗时任务,使用多进程是必不可少的。而在 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多进程函数相关推荐

  1. 使用进程池模拟多进程爬取url获取数据,使用进程绑定的回调函数去处理数据...

    1 # 使用requests请求网页,爬取网页的内容 2 3 # 模拟使用进程池模拟多进程爬取网页获取数据,使用进程绑定的回调函数去处理数据 4 5 import requests 6 from mu ...

  2. python并发处理list数据_python并发编程之多进程2--------数据共享及进程池和回调函数...

    一.数据共享 1.进程间的通信应该尽量避免共享数据的方式 2.进程间的数据是独立的,可以借助队列或管道实现通信,二者都是基于消息传递的. 虽然进程间数据独立,但可以用过Manager实现数据共享,事实 ...

  3. Python之路 34:并发与并行、锁(GIL、同步锁、死锁与递归锁)、信号量、线程队列、生消模型、进程(基础使用、进程通信、进程池、回调函数)、协程

    内容: 同步锁 死锁.递归锁 信号量和同步对象(暂时了解即可) 队列------生产者和消费者模型 进程(基础使用.进程通信.进程池.回调函数) 协程 一.并发并行与同步异步的概念 1.1.并发和并行 ...

  4. 进程间的数据共享、进程池的回调函数和线程初识、守护线程

    一.进程的数据共享 进程间数据是独立的,可以借助于队列或管道实现通信,二者都是基于消息传递的 虽然进程间数据独立,但可以通过Manager实现数据共享.把所有实现了数据共享的比较便捷的类都重新又封装了 ...

  5. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 一 | mmap 函数简介 )

    文章目录 一.mmap 简介 二.mmap 函数作用 一.mmap 简介 mmap 函数的作用是 将 文件 映射到 内存中 , 映射的单位必须是 PAGE_SIZE ; mmap 函数引入头文件 : ...

  6. linux exec 二程序,二十五、Linux 进程与信号---exec函数

    25.1 介绍 在用 fork 函数创建子进程后,子进程往往要调用一种 exec 函数以执行另一个程序 当进程调用一种 exec 函数时,该进程完全由新程序代换,替换原有进程的正文,而新程序则从其 m ...

  7. 进程线程005 SwapContext函数分析

    文章目录 线程切换与TSS 内核堆栈 内核堆栈结构 调用API进零环 SwapContext代码分析 线程切换与FS SwapContext代码分析 SwapContext的其他问题 SwapCont ...

  8. 4进程原语:fork()函数,getpid()函数和getppid()函数,getuid()函数,getgid()函数,vfork()

     1fork()函数 子进程复制父进程的0到3g空间和父进程内核中的PCB,但id号不同.fork调用一次返回两次,有以下特点: A:父进程中返回子进程ID B:子进程中返回0 C:读时共享,写时 ...

  9. UNIX环境编程学习笔记(19)——进程管理之fork 函数的深入学习

    在"进程控制三部曲"中,我们学习到了 fork 是三部曲的第一部,用于创建一个新进程.但是关于 fork 的更深入的一些的东西我们还没有涉及到,例如,fork 创建的新进程与调用进 ...

最新文章

  1. Java改知能机_Java 面试突击之 Java 并发知识基础 进阶考点全解析
  2. 序列联配(alignment)和数据库搜索方法简介
  3. python中常用的推导(字典推导和列表推导)
  4. 一个设计元素很多的网站
  5. 疫情加速中国服务器采购 数字化转型成为增长“新引擎”
  6. java 快速排序算法简单_排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序......
  7. [梦]2005年9月1日
  8. 环评图件制作-数据处理+图件制作(weixin公众号【图说GIS】)
  9. 个体营业执照与公司营业执照的区别
  10. 计算机操作系统锁定如何解锁,笔记本键盘锁定,小编教你笔记本键盘锁定怎么解锁...
  11. Error: Unresolved node modules: vue
  12. Excel合并表格之vba
  13. 图像拼接(八):拼接多幅图像+Matlab实现+Stanford Open Course
  14. VB 生成0~1的随机小数(不包含1),再用VB,感慨万千
  15. python学习笔记全过程_Python学习过程笔记整理(四)
  16. 电话号码归属地批量查询软件选择需谨慎
  17. Vue3+ElementPlus 表格分页组件封装
  18. leetcode13——步长k的差值小于t的元素组,包含1的正方形面积,完全二叉树的结点个数,矩形重叠面积,汇总区间
  19. 三万块钱6天的区块链培训,我学会了搭建区块链系统框架?
  20. linux ntp时间立即同步命令_Linux系统时间同步方法小结

热门文章

  1. 【数据结构总结】第八章 排序
  2. linux安装指定mysql版本安装,linux yum安装指定版本mysql
  3. portainer 启动mysql_Docker管理工具Portainer
  4. logrotate测试_使用 logrotate 对 apache/nginx 日志切割
  5. Java黑皮书课后题第7章:*7.21(整数求和)编写程序,从命令行输入不定数目的整数,然后显示它们的和
  6. Java黑皮书课后题第3章:*3.3(代数:求解2*2线性方程)编写程序,提示用户输入a、b、c、d、e和f,然后显示结果
  7. oracle resetlogs 误删,oracle undo表空间误删恢复
  8. Java Decimal范围_Java BigDecimal初探
  9. 列表数据提交_Mybatis-实现数据的增删改查
  10. vue为p标签_通过vue.js几个基本操作,理解一下什么是插槽「606」