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模块创建和使用子进程的更多相关文章

  1. 在Python程序中的进程操作,multiprocess.Process模块

    在python程序中的进程操作 之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创建的.因此,运行起 ...

  2. python 全栈开发,Day38(在python程序中的进程操作,multiprocess.Process模块)

    昨日内容回顾 操作系统纸带打孔计算机批处理 —— 磁带 联机 脱机多道操作系统 —— 极大的提高了CPU的利用率 在计算机中 可以有超过一个进程 进程遇到IO的时候 切换给另外的进程使用CPU 数据隔 ...

  3. Swoole 进程管理模块 Process 之单进程的使用

    PHP 自带的 pcntl,存在很多不足,如: 没有提供进程间通信的功能: 不支持重定向标准输入和输出: 只提供了 fork 这样原始的接口,容易使用错误: Swoole\Process 提供了如下特 ...

  4. 创建多进程之multiprocess包中的process模块

    创建多进程之multiprocess包中的process模块 1.process模块是一个创建进程的模块 Process([group [, target [, name [, args [, kwa ...

  5. 使用multiprocessing模块创建多进程

    # 使用multiprocessing模块创建多进程 # multiprcessing模块提供了一个Process类来描述一个进程对象. # 创建子进程时,只需要传入一个执行函数和函数的参数,即可完成 ...

  6. day 30 1.操作系统原理 2. Process 模块学习

    进程: 起源:进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操作系统的其他所有内容都是围绕进程的概念展开的.所以想要真正了解进程,必须事先了解操作 ...

  7. 第三十天- 进程 Process模块 空间隔离

    1.进程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体: ...

  8. Node.js进程管理之Process模块

    在前面Node.js事件运行机制也有提到,Node.js应用在单个线程运行,但是现在大部分服务器都是多处理器,为了方便使用多个进程,Node.js提供了3个模块.Process模块提供了访问正在运行的 ...

  9. nodejs-Child Process模块

    JavaScript 标准参考教程(alpha) 草稿二:Node.js Child Process模块 GitHub TOP Child Process模块 来自<JavaScript 标准参 ...

随机推荐

  1. C++ 面向对象程序设计复习大纲

     这是我在准备C++考试时整理的提纲,如果是通过搜索引擎搜索到这篇博客的师弟师妹,建议还是先参照PPT和课本,这个大纲也不是很准确,自己总结会更有收获,多去理解含义,不要死记硬背,否则遇到概念辨析题会 ...

  2. MySQL插入数据时报错Cause: java.sql.SQLException: #HY000的解决方法

    数据库中有字段要求不能为空,但是insert插入的时候,改字段没有值

  3. Git详细学习教程

    作者:gafish https://github.com/gafish/gafish.github.com Git简介 Git 是一种分布式版本控制系统,它可以不受网络连接的限制,加上其它众多优点,目 ...

  4. ASP.NET MVC教程三:ASP.NET MVC部署方式

    ASP.NET MVC编写的程序需要部署到IIS上面才能进行访问,部署方式分为两种. 一.直接用源代码部署 第一种方式可以直接使用源代码进行部署.部署步骤: 1.新建网站 在IIS里面选择网站,然后右 ...

  5. jQuery跳转到另一个页面以及原生js跳转到另一个页面

    1.原生js我们可以利用http的重定向来跳转 window.location.replace("https://www.cnblogs.com/pythonywy/"); 2.原 ...

  6. 剑指offer笔记面试题12----矩阵中的路径

    题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左.右.上.下移动一格.如果一条路径经过了矩阵的某一格,那么该路径 ...

  7. jQuery学习笔记Fisrt Day

    跳过JS直接JQUERY,“不愧是你”. 对就是我. 今天开始jQuery学习第一天. click事件方法: 鼠标点击 dbl事件方法: 双击鼠标 mouseenter事件方法: 鼠标进入 mouse ...

  8. Thymeleaf对象的使用:字符串对象

    Thymeleaf主要使用 org.thymeleaf.expression.Strings 类处理字符串,在模板中使用 #strings 对象来处理字符串. 开发环境:IntelliJ IDEA 2 ...

  9. Angular回顾(1)

    一.前端基础 HTML:超文本标记语言,文档排版. DOM:文档对象模型. JS: 脚本语言,解释执行:动态操作DOM,服务器交互,用户交互. CSS:层叠样式表. 二.Angular前提 TypeS ...

  10. 成功安装SQL Server实例后 无法找到SQL Server Configuration Manager工具的解决方案

    有一次成功安装SQL Server实例后 ,但是在所有程序中无法找到SQL Server Configuration Manager工具,以下步骤是我们当时的解决方案.最后成功将这个工具的转移到了桌面 ...