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 标准参 ...
随机推荐
- NumPy 会自动检测并利用 GPU 吗?
PyTorch 官网 60 分钟入门教程在介绍什么是 PyTorch 时有一句话:A replacement for NumPy to use the power of GPUs PyTorch 是 ...
- [C]链接和生存周期
链接和生存周期的区别: 链接是标识符的属性: 生存周期是对象的属性: 链接可以是外部(external),内部(internal)或没有(none): 生存周期可以是自动的.静态的,或已分配的(all ...
- [译]Vulkan教程(28)Image视图和采样器
[译]Vulkan教程(28)Image视图和采样器 Image view and sampler - Image视图和采样器 In this chapter we're going to creat ...
- Cisco学习记录(二):路由及网络设备配置
本篇我们利用cisco packet tracer搭建一个简单的网络.我们在左下方的设备中尝试选择创建两个4321路由器和一个3560-24PS Multilayer交换机,然后在左下方的电缆线中选择 ...
- 递归找到多级文件夹中所有pdf文件的py程序
因个人需要,写了一个可以递归找到多级文件夹中所有pdf的小程序,发布出来供有需要的人参考或使用. import os import re import shutil from os.path impo ...
- 关于ASP.NET配置
字符串加密打开Vs的开发人员命令提示符 //加密web.config文件的连接字符串aspnet_regiis.exe -pef "connectionStrings" " ...
- Java描述设计模式(12):外观模式
本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.场景描述 在移动互联网没有普及之前,去饭店吃饭的流程大致如下:选座位,排队,点菜,结账.后来移动互联网普及,通过手机APP就 ...
- 工作笔记 之 Linux服务搭建
No.1 linux环境下安装nginx步骤 Nginx (engine x) 是一款轻量级的Web 服务器.反向代理服务器.电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行. ...
- .Net Core 3.0后台使用httpclient请求网络网页和图片_使用Core3.0做一个简单的代理服务器
目标:使用.net core最新的3.0版本,借助httpclient和本机的host域名代理,实现网络请求转发和内容获取,最终显示到目标客户端! 背景:本人在core领域是个新手,对core的使用不 ...
- 理解并运用TP5.1-Facade
1.内容介绍 深入解析tp5.1与laravel 中Facade底层原理实现 1. 什么是Facade 2. 为什么需要有什么好处 3. Facade实现原理 4. 功能实现. 5. 容器注入 2. ...