php 请求间通信,PHP进程间通信

本文探讨了PHP通过pcntl扩展实现多进程,以提升短信通知速度。重点在于进程间通信难题和资源抢占,以及为何PHP多进程编程复杂。作者通过实例演示了如何利用多进程加速任务,并揭示了选择其他语言如Python或Java的原因。
摘要由CSDN通过智能技术生成

PHP作为解释器运行通过线程或者进程都能实现(如果使用Apache,那么就可能使用多线程模型。使用php-fpm,就是使用多进程模型,这里以多进程模型解释)。服务器每接收到一个请求就要起一个PHP进程,平均一个PHP进程消耗内存2M左右(默认最大为8M,参数可以设置)。独立的进程让PHP能专一的做自己的解释工作,程序员也从复杂的代码逻辑中走出来,不用担心资源的竞争和各种锁问题。独立进程虽好但这也导致想通过多进程或者异步来提速成本非常的高(主要是开发难度)。如果一定要通过PHP实现多进程和异步其实是很容易做到的。

PHP有很多第三方扩展,比如Swoole能让PHP像Node一样实现异步。PHP官方扩展库pcntl_*能很简单的实现多进程。扩展虽好,但实际应用时切忌要慎重,便利的同时风险也来了。比如对多进程的控制,处理不好很容易导致程序死锁,CPU内存爆表、服务器宕机。异步回调的Coding方式与PHP本身的编程思想有一定出入,驾驭不好也是灾难。

当然也不能说的太吓人,在实际的项目中我们有很多场景不得不考虑通过多进程或者异步来优化程序。这里举一个很常见的例子『发送消息通知』,比如短信和邮件。这里说一个实际的场景:企业需要给200W用户发短信通知,短信接口支持最大100次/秒的调用频率,短信接口每次调用耗时300毫秒。如果单进程跑脚本的话,需要7天才能把短信发完。如果我们起30个进程,每秒能发送100条短信,6个小时内能发完,能提速30倍。优化方案确定之后,我们再看如何通过PHP去实现这样一个脚本。

//通过pcntl扩展创建多进程,参见如下代码;

function demo(array $phoneList){

$cnt = count($phoneList); //测试数组大小

$slice = 30; //需要调用的进程数量

$master = array_chunk($phoneList,floor($cnt/$slice));

$childList = [];

while($slice >= 0)

{

$pid = pcntl_fork();

if($pid > 0){

$childList[$pid] = 1;

//$pid>0表示当前还在执行父进程的代码

//这里最好啥都不做,每次执行pcntl_fork都会执行这里的代码。

//这里的代码执行完之后 会将$pid设置为0,然后jump到pcntl_fork代码之后,重新做判断;

}elseif($pid == 0){

//这里写我们的逻辑

foreach($master[$slice] as $val)

{

//这里发生短信

echo sprintf("%s Child:%s \r\n",$slice,$val);

}

//子进程执行完之后务必需要关闭;

exit();

}else

{

//程序发生错误也需要关闭程序

exit();

}

$slice--;

}

// 等待所有子进程结束后回收资源

while(!empty($childList)){

$childPid = pcntl_wait($status);

if ($childPid > 0){

unset($childList[$childPid]);

}

}

}

/** 运行的结果如下,phone不是连续的

Slice id:19,phone:66558

Slice id:23,phone:79921

Slice id:19,phone:66559

Slice id:23,phone:79922

Slice id:19,phone:66560

Slice id:23,phone:79923

Slice id:19,phone:66561

Slice id:23,phone:79924

Slice id:19,phone:66562

Slice id:23,phone:79925

**/

通过pcntl扩展,几句代码就使用多进程将发消息通知的功能提速了30倍。不过这么简单的多进程编码,我为什么会在文章开始形容的如此复杂呢?

重点和难点还是进程间通信,因为我们给用户发短信的每个子进程是相对独立的,进程之间没有通信,不会互相传递数据状态。所以不会发生资源抢占与锁问题。假如需求发生变化,我们需要按用户的活跃度高低给用户发短信,该怎么做?

通俗点解释如下:一个盘子里有30个苹果,需要发给30个人,由3个人负责发苹果。最简单的办法就是我们先把苹果分成3份,3个人一人一份,很快就能发完。但是如果我们要按照苹果的大小顺序去发,把大苹果先发出去,此时我们就没办法分成3份了,只能三个人互相去挣当前最大的,很容易就打起来。那该怎么做呢?最常见的办法就是使用一个工具把所有苹果按由大到下的顺序放在里面,每次只能取一个,这样就解决了资源抢占的问题。

关于进程间资源抢占的问题非常的复杂,编码难度非常高,这也是为什么很少使用PHP跑多进程的原因。当需要用到多进程时我们更愿意去使用Python或者Java,它们对多线程封装的更好。需要重点说的是PHP并不是不能写多进程的程序,也不是像其他人说的不稳定,而是编码费时,维护成本高。

标签:Slice,间通信,phone,进程,pcntl,PHP,id

来源: https://www.cnblogs.com/qiguaideta/p/11572725.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值