PHP多进程处理并行处理任务实例(转,备用)
本文目的
本文通过例子讲解linux环境下,使用php进行并发任务处理,以及如何通过pipe用于进程间的数据同步。
PHP多进程
通过pcntl_XXX系列函数使用多进程功能。注意:pcntl_XXX只能运行在php CLI(命令行)环境下,在web服务器环境下,会出现无法预期的结果,请慎用!
管道PIPE
管道用于承载简称之间的通讯数据。为了方便理解,可以将管道比作文件,进程A将数据写到管道P中,然后进程B从管道P中读取数据。php提供的管道操作API与操作文件的API基本一样,除了创建管道使用posix_mkfifo函数,读写等操作均与文件操作函数相同。当然,你可以直接使用文件模拟管道,但是那样无法使用管道的特性了。
僵尸进程
子进程结束时,父进程没有等待它(通过调用wait或者waitpid),那么子进程结束后不会释放所有资源(浪费呀!),这种进程被称为僵尸进程,他里面存放了子进程结束时的相关数据,如果僵尸进程过多,会占用大量系统资源(如内存),影响机器性能。
代码
<?php
define("PC", ); // 进程个数
define("TO", ); // 超时
define("TS", ); // 事件跨度,用于模拟任务延时
if (!function_exists('pcntl_fork')) {
die("pcntl_fork not existing");
}
// 创建管道
$sPipePath = "my_pipe.".posix_getpid();
if (!posix_mkfifo($sPipePath, )) {
die("create pipe {$sPipePath} error");
}
// 模拟任务并发
for ($i = ; $i < PC; ++$i ) {
$nPID = pcntl_fork(); // 创建子进程
if ($nPID == ) {
// 子进程过程
sleep(rand(,TS)); // 模拟延时
$oW = fopen($sPipePath, 'w');
fwrite($oW, $i."\n"); // 当前任务处理完比,在管道中写入数据
fclose($oW);
exit(); // 执行完后退出
}
}
// 父进程
$oR = fopen($sPipePath, 'r');
stream_set_blocking($oR, FALSE); // 将管道设置为非堵塞,用于适应超时机制
$sData = ''; // 存放管道中的数据
$nLine = ;
$nStart = time();
while ($nLine < PC && (time() - $nStart) < TO) {
$sLine = fread($oR, );
if (empty($sLine)) {
continue;
}
echo "current line: {$sLine}\n";
// 用于分析多少任务处理完毕,通过‘\n’标识
foreach(str_split($sLine) as $c) {
if ("\n" == $c) {
++$nLine;
}
}
$sData .= $sLine;
}
echo "Final line count:$nLine\n";
fclose($oR);
unlink($sPipePath); // 删除管道,已经没有作用了
// 等待子进程执行完毕,避免僵尸进程
$n = ;
while ($n < PC) {
$nStatus = -;
$nPID = pcntl_wait($nStatus, WNOHANG);
if ($nPID > ) {
echo "{$nPID} exit\n";
++$n;
}
}
// 验证结果,主要查看结果中是否每个任务都完成了
$arr2 = array();
foreach(explode("\n", $sData) as $i) {// trim all
if (is_numeric(trim($i))) {
array_push($arr2, $i);
}
}
$arr2 = array_unique($arr2);
if ( count($arr2) == PC) {
echo 'ok';
} else {
echo "error count " . count($arr2) . "\n";
var_dump($arr2);
}
# time php fork.php
current line: current line: current line: current line: current line: Final line count:
exit
exit
exit
exit
exit
exit
exit
exit
exit
exit
error count
array() {
[]=>
string() ""
[]=>
string() ""
[]=>
string() ""
[]=>
string() ""
[]=>
string() ""
} real 0m4.199s
user 0m1.840s
sys 0m1.554s
摘自:https://blog.csdn.net/u014511737/article/details/47003885
PHP多进程处理并行处理任务实例(转,备用)的更多相关文章
- PHP多进程处理并行处理任务实例
本文目的 本文通过例子讲解linux环境下,使用php进行并发任务处理,以及如何通过pipe用于进程间的数据同步.写得比较简单,作为备忘录. PHP多进程 通过pcntl_XXX系列函数使用多进程功能 ...
- Python多进程并发(multiprocessing)用法实例详解
http://www.jb51.net/article/67116.htm 本文实例讲述了Python多进程并发(multiprocessing)用法.分享给大家供大家参考.具体分析如下: 由于Pyt ...
- IOS开发教程之put上传文件的服务器的配置及实例分享-备用
感谢大神分享 1,HTTP常见的方法 GET 获取指定资源 POST 2M 向指定资源提交数据进行处理请求,在RESTful风格中用于新增资源 HEAD 获取指定资源头部信息PUT 替换指定资源(不支 ...
- socketserver 多进程、多线程应用实例
1.线程池,ThreadingTCPServer #coding=utf-8 ''' 可并发,客户端互不影响,可以保持长连接,客户端发送消息 也不要求加 \r\n ''' #线程池(windows 可 ...
- php多进程和多线程的比较
前言 最近在学习php多进程和多线程的编程.说实话,这两样在工作中几乎都没有用到,毕竟php并不以异步处理擅长,对于网络请求同步处理可以解决绝大多数问题.但是既然有这样的机制,也了解一下,对于以后接触 ...
- 有用PHP依赖管理工具Composer新手教程
PHP依赖管理工具Composer新手教程 Composer 是 PHP 的一个依赖管理工具.它同意你申明项目所依赖的代码库,它会在你的项目中为你安装他们. 依赖管理 Composer 不是一个包管理 ...
- 基于mysqld_multi实现MySQL 5.7.24多实例多进程配置
学习环境: 操作系统 IP地址 主机名 软件包 备注 CentOS7.5 192.168.200.111 localhost 实验初始配置:所有主机关闭防火墙与selinux [root@ ...
- asp.net core系列 27 EF模型配置(索引,备用键,继承)
一.索引 索引是许多数据存储中的常见概念.虽然它们在数据存储中的实现可能会有所不同,但它们可用于更有效地基于列(或列集)进行查找.按照约定,用作外键每个属性 (或组的属性) 会自动创建索引.无法使用数 ...
- uwsgi多进程配合kafka-python消息无法发送
在工作中,使用uwsgi部署项目,其中uwsgi设置为多进程,并且python中使用了kafka-python模块作为生产者不断产生数据,但上线不久后几乎所有的生产者消息都报:KafkaTimeout ...
随机推荐
- ZOJ 3781 - Paint the Grid Reloaded - [DFS连通块缩点建图+BFS求深度][第11届浙江省赛F题]
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 Time Limit: 2 Seconds Me ...
- PyQt5标准对话框
很全的Qt的标准对话框,包含QInputDialog.QColorDialog.QFontDialog.QMessageBox.QOpenFileDialog... 全部是由官网的C++版本,转换成P ...
- 第三课:JAVA反射机制
基础的不想写啦,好了,直接上JAVA反射机制吧: 类对象概念: 所有的类,都存在一个类对象,这个类对象用于提供类层面的信息,比如有几种构造方法, 有多少属性,有哪些普通方法. JAVA类,他们的区别在 ...
- 图片放大_css3
.flash_little_img{position:relative;}.flash_little_img{width:500px;height:333px;border:none; margin: ...
- iOS入门怎样选择Swift和objective-c
版权声明:本文为博主原创文章,未经博主同意不得转载.博主微信:lofocus https://blog.csdn.net/cuibo1123/article/details/28261795 学oc吧 ...
- for和foreach的区别
public class Program { public static void Main() { Program program = new Program(); program.For();// ...
- Linux定时任务出现问题时正确的解决步骤
但凡是提供服务的,都要有本账.软件服务也不例外.无论是Apache,Nginx,还是我们自己搭建的网站,日志是标配.这里的日志就是一本账. 当定时任务出现问题时,正确的处理步骤是: 1,定时任务服务是 ...
- [LeetCode] 112. Path Sum_Easy tag: DFS
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all ...
- How to enable TLS 1.2 on Windows Server 2008 R2
Problem How to enable TLS 1.2 on Windows Server 2008 R2? Resolution QuoVadis recommends enabling and ...
- boost--smart_ptr库
C++没有类似Java.C#等语言的垃圾回收机制,内存管理是最为头痛的工作. new.delete以及指针的不恰当运用是C++中造成资源获取/释放问题的根源. 智能指针是解决这些问题的一种方案,boo ...