swoole的process模块创建和使用子进程
swoole中为我们提供了一个进程管理模块 Process,替换PHP的 pcntl 扩展,方便我们创建进程,管理进程,和进程间的通信。
swoole提供了2种进程间的通信:
1、基于 unix socket 的管道 pipe。
2、基于 sysvmsg 的消息队列。
我们可以通过 new swoole_process() 快速的创建一个进程,默认会创建一个 SOCK_DGRAM 类型的管道,用于进程间的通信,当然可以设置成其他类型,也可以不创建。
一、通过同步阻塞管道进行进程间通信
<?php $worker_process_nums = 5;
$worker_process = []; for ($i = 0; $i < $worker_process_nums; $i++) {
//创建子进程
//默认为每个子进程创建一个管道,如果不想创建设置$pipe_type参数为false
//注意管道默认是同步阻塞,半双工,如果读取不到数据就会阻塞
$worker = new swoole_process(function (swoole_process $worker) {
//注意,如果主进程中不写数据write(),那么子进程这里read()就会阻塞
$task = json_decode($worker->read(), true); //进行计算任务
$tmp = 0;
for ($i = $task['start']; $i < $task['end']; $i++) {
$tmp += $i;
} echo '子进程 PID : ', $worker->pid, ' 计算 ', $task['start'], ' - ', $task['end'], ' 结果 : ', $tmp, PHP_EOL;
//往管道中写入计算的结果
$worker->write($tmp);
//子进程退出
$worker->exit();
}); //保存子进程
$worker_process[$i] = $worker; //启动子进程
$worker->start();
} //往每个子进程管道中投递任务
for ($i = 0; $i < $worker_process_nums; $i++) {
$worker_process[$i]->write(json_encode([
'start' => mt_rand(1, 10),
'end' => mt_rand(50, 100),
]));
} //父进程监听子进程退出信号,回收子进程,防止出现僵尸进程
swoole_process::signal(SIGCHLD, function ($sig) {
//必须为false,非阻塞模式
while ($ret = swoole_process::wait(false)) {
echo "子进程 PID : {$ret['pid']} 退出\n";
}
});
二、通过 swoole_event_add 将管道设为异步,来进行通信
<?php $worker_process_nums = 5;
$worker_process = []; for ($i = 0; $i < $worker_process_nums; $i++) {
$worker = new swoole_process(function ($worker) {
//在子进程中给管道添加事件监听
//底层会自动将该管道设置为非阻塞模式
//参数二,是可读事件回调函数,表示管道可以读了
swoole_event_add($worker->pipe, function ($pipe) use ($worker) {
$task = json_decode($worker->read(), true); $tmp = 0;
for ($i = $task['start']; $i < $task['end']; $i++) {
$tmp += $i;
}
echo "子进程 : {$worker->pid} 计算 {$task['start']} - {$task['end']} \n";
//子进程把计算的结果,写入管道
$worker->write($tmp);
//注意,swoole_event_add与swoole_event_del要成对使用
swoole_event_del($worker->pipe);
//退出子进程
$worker->exit();
});
}); $worker_process[$i] = $worker; //启动子进程
$worker->start();
} for ($i = 0; $i < $worker_process_nums; $i++) {
$worker = $worker_process[$i]; $worker->write(json_encode([
'start' => mt_rand(1, 10),
'end' => mt_rand(50, 100),
])); //主进程中,监听子进程管道事件
swoole_event_add($worker->pipe, function ($pipe) use ($worker) {
$result = $worker->read();
echo "子进程 : {$worker->pid} 计算结果 {$result} \n";
swoole_event_del($worker->pipe);
});
} //父进程监听子进程退出信号,回收子进程,防止出现僵尸进程
swoole_process::signal(SIGCHLD, function ($sig) {
//必须为false,非阻塞模式
while ($ret = swoole_process::wait(false)) {
echo "子进程 PID : {$ret['pid']} 退出\n";
}
});
三、使用消息队列来完成进程间通信
<?php $worker_process_nums = 5;
$worker_process = []; for ($i = 0; $i < $worker_process_nums; $i++) {
//注意,这里将参数$pipe_type设为false,表示不创建管道
$worker = new swoole_process(function ($worker) {
$task = json_decode($worker->pop(), true); $tmp = 0;
for ($i = $task['start']; $i < $task['end']; $i++) {
$tmp += $i;
}
echo "子进程 : {$worker->pid} 计算 {$task['start']} - {$task['end']} \n";
$worker->push($tmp);
$worker->exit();
}, false, false); //使用消息队列,作为进程间的通信
//注意,消息队列是共享的
$worker->useQueue(); $worker_process[$i] = $worker; //启动子进程
$worker->start();
} for ($i = 0; $i < $worker_process_nums; $i++) {
//只需用一个子进程发送消息即可,因为消息队列是共享的
$worker_process[0]->push(json_encode([
'start' => mt_rand(1, 10),
'end' => mt_rand(50, 100),
]));
} //注意,这里要暂停,防止加入队列的任务,立刻被主进程读出来。
sleep(1); for ($i = 0; $i < $worker_process_nums; $i++) {
$result = $worker_process[0]->pop();
echo "计算结果 : {$result} \n";
} //父进程监听子进程退出信号,回收子进程,防止出现僵尸进程
swoole_process::signal(SIGCHLD, function ($sig) {
//必须为false,非阻塞模式
while ($ret = swoole_process::wait(false)) {
echo "子进程 PID : {$ret['pid']} 退出\n";
}
});
四、进程可以通过 signal 监听信号,和 alarm 设置定时器。
我们可以在父进程上设置监听信号,当子进程退出时,重新挂起子进程。
也可以设置定时器,通过 swoole_process::kill($pid, 0); 定时检测进程是否存活。
<?php //每隔1秒触发SIGALAM信号
//注意,alarm不能和Timer同时使用
swoole_process::alarm(1000 * 1000, 0); swoole_process::signal(SIGALRM, function ($signo) {
static $cnt = 0;
$cnt++;
echo "时钟定时信号\n"; if ($cnt > 10) {
//清除定时器
swoole_process::alarm(-1);
}
}); swoole_process::signal(SIGINT, function ($signo) {
echo "我被ctrl+c了\n"; //退出主进程,不然将一直无法正常退出
exit(0);
});
swoole的process模块创建和使用子进程的更多相关文章
- 在Python程序中的进程操作,multiprocess.Process模块
在python程序中的进程操作 之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创建的.因此,运行起 ...
- python 全栈开发,Day38(在python程序中的进程操作,multiprocess.Process模块)
昨日内容回顾 操作系统纸带打孔计算机批处理 —— 磁带 联机 脱机多道操作系统 —— 极大的提高了CPU的利用率 在计算机中 可以有超过一个进程 进程遇到IO的时候 切换给另外的进程使用CPU 数据隔 ...
- Swoole 进程管理模块 Process 之单进程的使用
PHP 自带的 pcntl,存在很多不足,如: 没有提供进程间通信的功能: 不支持重定向标准输入和输出: 只提供了 fork 这样原始的接口,容易使用错误: Swoole\Process 提供了如下特 ...
- 创建多进程之multiprocess包中的process模块
创建多进程之multiprocess包中的process模块 1.process模块是一个创建进程的模块 Process([group [, target [, name [, args [, kwa ...
- 使用multiprocessing模块创建多进程
# 使用multiprocessing模块创建多进程 # multiprcessing模块提供了一个Process类来描述一个进程对象. # 创建子进程时,只需要传入一个执行函数和函数的参数,即可完成 ...
- day 30 1.操作系统原理 2. Process 模块学习
进程: 起源:进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操作系统的其他所有内容都是围绕进程的概念展开的.所以想要真正了解进程,必须事先了解操作 ...
- 第三十天- 进程 Process模块 空间隔离
1.进程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体: ...
- Node.js进程管理之Process模块
在前面Node.js事件运行机制也有提到,Node.js应用在单个线程运行,但是现在大部分服务器都是多处理器,为了方便使用多个进程,Node.js提供了3个模块.Process模块提供了访问正在运行的 ...
- nodejs-Child Process模块
JavaScript 标准参考教程(alpha) 草稿二:Node.js Child Process模块 GitHub TOP Child Process模块 来自<JavaScript 标准参 ...
随机推荐
- vue axios 在 edge 浏览器下的bug
Edge 浏览器的版本: Microsoft Edge 42.17134.1.0Microsoft EdgeHTML 17.17134 当请求为POST 时,转换为 GET,并且始终报 “来自缓存 ...
- vue介绍以及相关概念理解大全
1.什么是vue 以官网的解释来说,vue是渐进式javascript框架.Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计 ...
- IT兄弟连 HTML5教程 CSS3揭秘 CSS常见的样式属性和值4
6 鼠标光标属性 在网页中默认的鼠标指针只有两种,一种是最普通的箭头,另一种是当移动到链接上时出现的“小手”.但现在越来越多的网页都使用了CSS鼠标指针技术,当将鼠标移动到链接上时,可以看到多种不同 ...
- 1025 PAT Ranking 双重排序
Programming Ability Test (PAT) is organized by the College of Computer Science and Technology of Zhe ...
- 一种简单实现Redis集群Pipeline功能的方法及性能测试
上一篇文章<redis pipeline批量处理提高性能>中我们讲到redis pipeline模式在批量数据处理上带来了很大的性能提升,我们先来回顾一下pipeline的原理,redis ...
- AttributeError: 'unicode' object has no attribute 'tzinfo' 未解决
Internal Server Error: /demo/machineinfo.htmlTraceback (most recent call last): File "C:\Python ...
- Web前端基础(18):jQuery基础(五)
1. 事件 前面我们介绍完js的事件流的概念之后,相信大家对事件流也有所了解了.那么接下来我们看一下jquery的事件操作. 在说jquery的每个事件之前,我们先来看一下事件对象 . 1.1 事件对 ...
- Bootstrap 时间日历插件bootstrap-datetimepicker配置与应用小结
Bootstrap时间日历插件bootstrap-datetimepicker配置与应用小结 by:授客 QQ:1033553122 1. 测试环境 win7 JQuery-3.2.1.min ...
- SDWebImage4.0之后加载gif不显示的解决方案
SDWebImage4.0之前 UIImageView *imgView = [UIImageView new]; imgView.contentMode = UIViewContentModeSca ...
- Android6.0 源码修改之Setting列表配置项动态添加和静态添加
写在前面 最近客户有个需求,要求增加操作Setting列表配置项的功能,是不是一脸懵,没关系,一图胜千言,接下来就上图.诺,就是这么个意思. 原来的列表配置项 增加了单个配置项 增 ...