当前位置: 首页 > news >正文

PHP多进程

我们都知道PHP是单进程执行的,PHP处理多并发主要是依赖服务器或PHP-FPM的多进程及它们进程的复用,但PHP实现多进程也意义重大,尤其是在后台Cli模式下处理大量数据或运行后台DEMON守护进程时,多进程的优势不用多说。

PHP的多线程也曾被人提及,但进程内多线程资源共享和分配的问题难以解决。PHP也有多线程想关的扩展 pthreads ,但据说不太稳定,且要求环境为线程安全,所用不多。

以前PHP群里的一位大神曾指导说后台PHP想进阶必然避不开多进程,正好公司里的守护进程也应用了PHP的多进程,结合着谷哥的各种资料和手册,总算理解了多进程,并自己写了一个小demo(在linux系统上实现的),用此文总结一下,如有错漏,谢谢提出。

要实现PHP的多进程,我们需要两个扩展 pcntl和 posix,安装方法这里不再赘述。


创建子进程

创建PHP子进程是多进程的开始,我们需要pcntl_fork()函数;

fork函数详解

pcntl_fork() — 在当前进程当前位置产生分支(子进程)。此函数创建了一个新的子进程后,子进程会继承父进程当前的上下文,和父进程一样从pcntl_fork()函数处继续向下执行,只是获取到的pcntl_fork()的返回值不同,我们便能从判断返回值来区分父进程和子进程,分配父进程和子进程去做不同的逻辑处理。

pcntl_fork()函数成功执行时会在父进程返回子进程的进程id(pid),因为系统的初始进程init进程的pid为1,后来产生进程的pid都会大于此进程,所以我们可以通过判断pcntl_fork()的返回值大于1来确实当前进程是父进程;

而在子进程中,此函数的返回值会是固定值0,我们也可以通过判断pcntl_fork()的返回值为0来确定子进程;

而pcntl_fork()函数在执行失败时,会在父进程返回-1,当然也不会有子进程产生。

fork进程实例

以下是fork子进程的一个简单的小例子:

    $ppid = posix_getpid();
    $pid = pcntl_fork();
    if ($pid == -1) {
        throw new Exception('fork子进程失败!');
    } elseif ($pid > 0) {
        cli_set_process_title("我是父进程,我的进程id是{$ppid}.");
     sleep(30); // 保持30秒,确保能被ps查到 } else { $cpid = posix_getpid(); cli_set_process_title("我是{$ppid}的子进程,我的进程id是{$cpid}."); sleep(30); }

这时介绍一下两个函数:

posix_getpid():获取当前进程的pid;

cli_set_process_title('响亮的名字'):为当前进程取一个响亮的名字。

运行这个例子,我们便能看到当前两个PHP进程了。 


管理子进程

创建好了进程,那么怎么对子进程进行管理呢?使用信号。

在计算机科学中,信号是Unix、类Unix以及其他POSIX兼容的操作系统中进程间通讯的一种有限制的方式。它是一种异步的通知机制,用来提醒进程一个事件已经发生。

分发信号处理器

我们通过在父进程接收子进程传来的信号,判断子进程状态,来对子进程进行管理。

我们需要在父进程里使用pcntl_signal()函数和pcntl_signal_dispatch()函数来给各个子进程安装信号处理器。

pcntl_signal (int $signo , callback $handler) 安装一个信号处理器;
        $signo是待处理的信号常量,callback是其处理函数

pcntl_signal_dispatch () 调用每个等待信号通过pcntl_signal()安装的处理器

PHP内常见的信号常量有:

        SIGCHLD     子进程退出成为僵尸进程会向父进程发送此信号
        SIGHUP      进程挂起
        SIGTEM      进程终止
        ...         // 其他请在手册中查看

安装并调用信号处理器后,一旦子进程有相应的信号返回给父进程,父进程就可以调用相应的callback函数对子进程处理;

处理子进程

对子进程的处理方法有:

posix_kill():此函数并不能顾名思义,它通过向子进程发送一个信号来操作子进程,在需要要时可以选择给子进程发送进程终止信号来终止子进程;

pcntl_waitpid():等待或返回fork的子进程状态,如果指定的子进程在此函数调用时已经退出(俗称僵尸进程),此函数将立刻返回,并释放子进程的所有系统资源,此进程可以避免子进程变成僵尸进程,造成系统资源浪费;

下面是两个函数的函数原型:

bool posix_kill ( int $pid , int $sig ) // 向进程id为$pid的进程发送$sig信号,$sig常见信号如上;

int pcntl_waitpid ( int $pid , int &$status [, int $options = 0 ] )  // 挂起当前进程的执行直到进程号为$pid的进程退出(如果$pid为-1,则等待任意一个子进程); 

总结

这就是PHP多进程的基础使用了,感兴趣的可以自己写一个demo试一试手了。

最后贴一下鸟哥所说的PHP多进程优点:

  1. 使用多进程, 子进程结束以后, 内核会负责回收资源
  2. 使用多进程,子进程异常退出不会导致整个进程Thread退出. 父进程还有机会重建流程.
  3. 一个常驻主进程, 只负责任务分发, 逻辑更清楚.

转载于:https://www.cnblogs.com/liliuguang/p/9897276.html

相关文章:

  • SpringMVC基础知识
  • MPAndroidChart 教程:Y轴 YAxis
  • 大快搜索数据爬虫技术实例安装教学篇
  • js递归,无限分级树形折叠菜单
  • Linux环境搭建及命令
  • 区块链教程Fabric1.0源代码分析Peer peer chaincode命令及子命令实现
  • 我的前端工具集(九)树工具重新封装和修改
  • Spring Cloud 2.x系列之网关zuul入门(三)
  • Can't create/write to file '/tmp/MLjnvU95' (Errcode: 13 - Permission denied)
  • 互融云保理业务系统助力企业快速拓展业务
  • 如何利用MongoDB打造TOP榜小程序
  • 4.时间复杂度和空间复杂度-2
  • 你真的懂Redis事务吗?
  • MySQL-去重留一
  • *p=a是把a的值赋给p,p=a是把a的地址赋给p。
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • 【刷算法】从上往下打印二叉树
  • canvas绘制圆角头像
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • dva中组件的懒加载
  • HTTP中GET与POST的区别 99%的错误认识
  • Median of Two Sorted Arrays
  • PHP 小技巧
  • Python_网络编程
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • 半理解系列--Promise的进化史
  • 订阅Forge Viewer所有的事件
  • 工作手记之html2canvas使用概述
  • 关于Flux,Vuex,Redux的思考
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • # 透过事物看本质的能力怎么培养?
  • ###C语言程序设计-----C语言学习(6)#
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (一)WLAN定义和基本架构转
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • * CIL library *(* CIL module *) : error LNK2005: _DllMain@12 already defined in mfcs120u.lib(dllmodu
  • ***检测工具之RKHunter AIDE
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .NET Reactor简单使用教程
  • .net 生成二级域名
  • .NET 中什么样的类是可使用 await 异步等待的?
  • .NET中两种OCR方式对比
  • @manytomany 保存后数据被删除_[Windows] 数据恢复软件RStudio v8.14.179675 便携特别版...
  • [ 常用工具篇 ] AntSword 蚁剑安装及使用详解
  • [@Controller]4 详解@ModelAttribute
  • []常用AT命令解释()
  • [Android Pro] Notification的使用
  • [C# 开发技巧]如何使不符合要求的元素等于离它最近的一个元素
  • [C#]手把手教你打造Socket的TCP通讯连接(一)
  • [C\C++]读入优化【技巧】