龙空技术网

swoole教程第一节:进程管理模块-(消息队列)

PHP编程爱好者 104

前言:

如今同学们对“php模块查看”大概比较关怀,我们都需要剖析一些“php模块查看”的相关资讯。那么小编也在网上收集了一些有关“php模块查看””的相关知识,希望兄弟们能喜欢,看官们快快来学习一下吧!

不多说,上代码

<?php$workers = [];$worker_num = 2;for($i = 0; $i < $worker_num; $i++){    $process = new swoole_process('callback_function', false, false);    $process->useQueue();    $pid = $process->start();    $workers[$pid] = $process;    //echo "Master: new worker, PID=".$pid."\n";}function callback_function(swoole_process $worker){    //echo "Worker: start. PID=".$worker->pid."\n";    //recv data from master    $recv = $worker->pop();    echo "From Master: $recv\n";    sleep(2);    $worker->exit(0);}foreach($workers as $pid => $process){    $process->push("hello worker[$pid]\n");}for($i = 0; $i < $worker_num; $i++){    $ret = swoole_process::wait();    $pid = $ret['pid'];    unset($workers[$pid]);    echo "Worker Exit, PID=".$pid.PHP_EOL;}

这段代码出自 消息队列

我想说五个点

swoole_process 的创建默认是创建的管道,当想用消息队列时,记得把参数设成false(其实我发现不写也行)useQueue要在start的之前调用,pop方法 默认是阻塞的一定一定要写wait(这里坑死不少人)

还有第五点注意事项,我接下来重点说,因为这个点卡了我好久。

嘛,demo里面只是说主进程向子进程发数据,没有子进程向主进程发数据,我就来加上吧

<?php$workers = [];$worker_num = 2;for($i = 0; $i < $worker_num; $i++){    $process = new swoole_process('callback_function',false,false);    $process->useQueue();    $pid = $process->start();    $workers[$pid] = $process;    //echo "Master: new worker, PID=".$pid."\n";}function callback_function(swoole_process $worker){    //echo "Worker: start. PID=".$worker->pid."\n";    //recv data from master    $recv = $worker->pop();    echo "From Master: $recv\n";    $worker->push(" \n   hehe   \n ");//这里子进程向主进程发送  hehe    sleep(2);//注意这里有个sleep    $worker->exit(0);}foreach($workers as $pid => $process){    $process->push("hello worker[$pid]\n");    $result = $process->pop();    echo "From worker: $result\n";//这里主进程,接受到的子进程的数据}for($i = 0; $i < $worker_num; $i++){    $ret = swoole_process::wait();    $pid = $ret['pid'];    unset($workers[$pid]);    echo "Worker Exit, PID=".$pid.PHP_EOL;}

运行结果完美,我就不贴了,

我看着代码,忽然发现自己没把sleep删掉,然后噩梦开始了

大家把上面代码的sleep注释后运行看看,我这里贴上我的运行结果

From Master: hello worker[3667]From worker:     hehe   PHP Warning:  swoole_process::push(): msgsnd() failed. Error: Invalid argument[22] in /home/sun/learn/swoole/process/demo.php on line 28PHP Warning:  swoole_process::pop(): msgrcv() failed. Error: Invalid argument[22] in /home/sun/learn/swoole/process/demo.php on line 29From worker: PHP Warning:  swoole_process::pop(): msgrcv() failed. Error: Identifier removed[43] in /home/sun/learn/swoole/process/demo.php on line 18From Master: PHP Warning:  swoole_process::push(): msgsnd() failed. Error: Invalid argument[22] in /home/sun/learn/swoole/process/demo.php on line 20Worker Exit, PID=3668Worker Exit, PID=3667

这就是我的报错,我看这个错误,发现第一个进程是完美执行的,和预先想的一样,错误出在主进程第二次发送消息到消息队列时出现的,主进程的数据发送出错了

哎呀,怎么回事,不明白。

其实故事是这样的

主进程创建两个子进程,这里没问题

主进程向第一个子进程发数据,第一个子进程收到后向主进程回发数据,这里也没问题

主进程再向第二个子进程发数据,好,出问题了,

那么 问题来了,第一个子进程做了什么我们不知道的事情?

请看这里 子进程临死前做了什么

$status是退出进程的状态码,如果为0表示正常结束,会继续执行PHP的shutdown_function,其他扩展的 清理工作

第一个子进程临死前把消息队列给埋了

换句话说,主进程再想往消息队列里写东西时写不了了,因为没有消息队列了。

那为什么刚开始有sleep的时候就没事呢?

因为趁着第一个子进程睡觉的时候,主进程和第二个子进程把事情做了

那么我们怎么办?怎么才能不让子进程摧毁消息队列??

把 swoole_process->exit(0) 改成 swoole_process->exit(1)了

这是我要说的第五点

多个子进程使用消息队列通讯一定写上 $process->exit(1)

好的,基本上遵守这五条,使用消息队列就不会有什么问题了。最后请记得升级自己的swoole版本,因为有些问题可能是因为你的版本太老了

作为web开发的佼佼者PHP并不逊色其他语言,加上swoole后更加是如虎添翼!进军通信 、物联网行业开发百度地图、百度订单中心等!年后更是霸占程序员招聘语言第二名,寒冬裁员期过后正是各大企业扩大招人的时期,现在市场初级程序员泛滥,进阶中高级程序员绝对是各大企业急需的人才,这套教程适合那些1-6年的PHP开发者进阶中高级提升自己,在金九银十中找到高薪职位!

领取方式:点赞关注小编后私信【资料】获取资料领取方式!

部分资料展示:

领取方式:点赞关注小编后私信【资料】获取资料领取方式!

标签: #php模块查看