Swoole 初级教程
1 . swoole 进程模块 process,模拟并发处理不同任务的案例
直接上代码
#!/usr/bin/php
<?php
use Swoole\Process;
class swoole
{
private $daemon;
public function __construct(){
$getopt = getopt("d:");
$this->daemon = ($getopt["d"] ?? "") == "true" ? true : false;
}
public function main(){
$redis = new redis();
$redis->connect("127.0.0.1");
$redis->setOption(Redis::OPT_READ_TIMEOUT,-1);
$this->daemon && Process::daemon();
while(true){
try {
if ($redis->ping() != "+PONG") {
$redis = new redis();
$redis->connect("127.0.0.1");
$redis->setOption(redis::OPT_READ_TIMEOUT, -1);
}
} catch (Exception $e) {
}
echo "启动监听任务 \n";
// redis阻塞进程, 等待任务进入
$data = $redis->brPop("list:swoole",0);
$forks = [];
for ($i=1;$i<=6;++$i){
// 将接受到的任务放到redis中执行
$process = $this->createProcess($data[1] ?? "");
$forks[$process->pid] = $process;
}
// 等待任务完成
while($ret = swoole_process::wait(true)) {
$pid = $ret['pid'];
$process = $forks[$pid];
// 保存结果到文件
// 重点:父进程 $process->read(); 读取子进程的结果执行执行一次。否则会阻塞父进程
file_put_contents("/data/wwwroot/php-cli/swoole.log",$process->read()."\n",FILE_APPEND);
}
}
}
/**
* 创建子进程并执行业务逻辑
* @param string $taskString
* @return Process
*/
private function createProcess(string $taskString){
$process = new Process(function(Process $worker)use($taskString) {
$pid = $worker->pid; // 获取当前子工作进程号
$worker->name("opop:{$pid}"); // 设置进程别名
co::sleep(rand(4,8)); // 模拟任务执行 耗时
$worker->write("成功 {$pid}->".$taskString); // 将业务逻辑写入管道, 通知主(父)进程
// 检测子进程存活的话,直接杀死退出子进程
if(Process::kill($pid,0)){
$worker->exit(0); // 杀死子进程
}
},false,1,true);
$process->start();
return $process;
}
}
(new swoole())->main();
启动及状态查看
# 守护进程启动,最好使用 nohup再加守护进程
$ nohup php swoole -d=true &
$ ps -ef | grep php
网友评论