php 的多进程实践
php的多进程处理依赖于pcntl扩展,通过pcntl_fork创建子进程来进行并行处理。
<?php
$pid = pcntl_fork(); if($pid == -1) {
//错误处理:创建子进程失败时返回-1.
die('fork error');
} else if ($pid) {
//父进程会得到子进程号,所以这里是父进程执行的逻辑
echo "parent \n";
//等待子进程中断,防止子进程成为僵尸进程。
pcntl_wait($status);
} else {
//子进程得到的$pid为0, 所以这里是子进程执行的逻辑。
echo "child \n"; exit;
}
<?php
$pid = pcntl_fork(); if($pid == -1) {
die('fork error');
} else if ($pid) {
sleep(3);
echo "parent \n";
pcntl_wait($status);
} else {
echo "child \n"; exit;
}
<?php
$pid = pcntl_fork(); if($pid == -1) {
die('fork error');
} else if ($pid) {
pcntl_wait ($status);
echo "parent \n";
} else {
sleep(3);
echo "child \n"; exit;
}
<?php
define('FORK_NUMS', 3); $pids = array(); for($i = 0; $i < FORK_NUMS; ++$i) {
$pids[$i] = pcntl_fork();
if($pids[$i] == -1) {
die('fork error');
} else if ($pids[$i]) {
pcntl_waitpid($pids[$i], $status);
echo "pernet \n";
} else {
sleep(3);
echo "child id:" . getmypid() . " \n";
exit;
}
}
上述代码,我们创建3个子进程,父进程分别挂起等待子进程结束后,输出parent。
child id:19090
pernet
child id:19091
pernet
child id:19092
pernet
<?php
define('FORK_NUMS', 3); $pids = array(); for($i = 0; $i < FORK_NUMS; ++$i) {
$pids[$i] = pcntl_fork();
if($pids[$i] == -1) {
die('fork error');
} else if ($pids[$i]) { } else {
sleep(3);
echo "child id:" . getmypid() . " \n";
exit;
}
} foreach($pids as $k => $v) {
if($v) {
pcntl_waitpid($v, $status);
echo "parent \n";
}
}
输出结果如下:
child id:19118
child id:19119
child id:19120
parent
parent
parent
为什么上述代码跟例4的输出结果不一样?
<?php
define('FORK_NUMS', 3);
$pids = array();
$fp = fopen('./test.log', 'wb');
$num = 1;
for($i = 0; $i < FORK_NUMS; ++$i) {
$pids[$i] = pcntl_fork();
if($pids[$i] == -1) {
die('fork error');
} else if ($pids[$i]) {
} else {
for($i = 0; $i < 5; ++$i) {
flock($fp, LOCK_EX);
fwrite($fp, getmypid() . ' : ' . date('Y-m-d H:i:s') . " : {$num} \r\n");
flock($fp, LOCK_UN);
echo getmypid(), ": success \r\n";
++$num;
}
exit;
}
}
foreach($pids as $k => $v) {
if($v) {
pcntl_waitpid($v, $status);
}
}
fclose($fp);
19507 : 2016-03-16 20:40:52 : 1
19507 : 2016-03-16 20:40:52 : 2
19507 : 2016-03-16 20:40:52 : 3
19507 : 2016-03-16 20:40:52 : 4
19507 : 2016-03-16 20:40:52 : 5
19509 : 2016-03-16 20:40:52 : 1
19509 : 2016-03-16 20:40:52 : 2
19509 : 2016-03-16 20:40:52 : 3
19509 : 2016-03-16 20:40:52 : 4
19509 : 2016-03-16 20:40:52 : 5
19508 : 2016-03-16 20:40:52 : 1
19508 : 2016-03-16 20:40:52 : 2
19508 : 2016-03-16 20:40:52 : 3
19508 : 2016-03-16 20:40:52 : 4
19508 : 2016-03-16 20:40:52 : 5
我们可以看到三个子进程的pid,它们分别执行了5次,时间几乎是在同时。但是$num的值并没像我们期望的那样从1-15进行递增。子进程中的变量是各自独立的,互不影响。子进程会自动复制父进程空间里的变量。
<?php
define('FORK_NUMS', 3);
$pids = array();
$fp = fopen('./test.log', 'wb');
$num = 1;
//共享内存段的key
$shmKey = 123;
//创建共享内存段
$shmId = shmop_open($shmKey, 'c', 0777, 64);
//写入数据到共享内存段
shmop_write($shmId, $num, 0);
for($i = 0; $i < FORK_NUMS; ++$i) {
$pids[$i] = pcntl_fork();
if($pids[$i] == -1) {
die('fork error');
} else if ($pids[$i]) {
//阻塞,等待子进程退出
//注意这里,如果是非阻塞的话,$num的计数会出现问题。
pcntl_waitpid($pids[$i], $status);
} else {
//读取共享内存段中的数据
$num = shmop_read($shmId, 0, 64);
for($i = 0; $i < 5; ++$i) {
fwrite($fp, getmypid() . ' : ' . date('Y-m-d H:i:s') . " : {$num} \r\n");
echo getmypid(), ": success \r\n";
//递增$num
$num = intval($num) + 1;
}
//写入到共享内存段中
shmop_write($shmId, $num, 0);
exit;
}
}
//shmop_delete不会实际删除该内存段,它将该内存段标记为删除。
shmop_delete($shmId);
shmop_close($shmId);
fclose($fp);
上述代码的运行结果如下:
19923 : 2016-03-17 00:05:18 : 1
19923 : 2016-03-17 00:05:18 : 2
19923 : 2016-03-17 00:05:18 : 3
19923 : 2016-03-17 00:05:18 : 4
19923 : 2016-03-17 00:05:18 : 5
19924 : 2016-03-17 00:05:18 : 6
19924 : 2016-03-17 00:05:18 : 7
19924 : 2016-03-17 00:05:18 : 8
19924 : 2016-03-17 00:05:18 : 9
19924 : 2016-03-17 00:05:18 : 10
19925 : 2016-03-17 00:05:18 : 11
19925 : 2016-03-17 00:05:18 : 12
19925 : 2016-03-17 00:05:18 : 13
19925 : 2016-03-17 00:05:18 : 14
19925 : 2016-03-17 00:05:18 : 15
这样我们就在进程间共享了$num的数据。
php 的多进程实践的更多相关文章
- python week08 并发编程之多进程--实践部分
一 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程.P ...
- Pytorch多进程最佳实践
预备知识 模型并行( model parallelism ):即把模型拆分放到不同的设备进行训练,分布式系统中的不同机器(GPU/CPU等)负责网络模型的不同部分 —— 例如,神经网络模型的不同网络层 ...
- Socket编程实践(4) --多进程并发server
1.Socket地址复用 int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); in ...
- 【云计算】使用supervisor管理Docker多进程-ntpd+uwsgi+nginx示例最佳实践
supervisor安装启动: apt-get install supervisor -y # start supervisord nodaemon /usr/bin/supervisord --no ...
- PHP多进程开发与Redis结合实践
原文:https://blog.51cto.com/laok8/2107892?source=drh 业务逻辑介绍: 用户在 APP 上发帖子,然后存储到 Redis 的 List 列表中 利用 Li ...
- Python中的多进程与多线程(一)
一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...
- 信息系统实践手记5-CACHE设计一例
说明:信息系统实践手记系列是系笔者在平时研发中先后遇到的大小的问题,也许朴实和细微,但往往却是经常遇到的问题.笔者对其中比较典型的加以收集,描述,归纳和分享. 摘要:此文描述了笔者接触过的部分信息系统 ...
- PHP多进程编程实例
这篇文章主要介绍了PHP多进程编程实例,本文讲解的是在Linux下实现PHP多进程编程,需要的朋友可以参考下 羡慕火影忍者里鸣人的影分身么?没错,PHP程序是可以开动影分身的!想完成任务,又觉得一个进 ...
- 《C++编程规范:101条规则、准则与最佳实践》学习笔记
转载:http://dsqiu.iteye.com/blog/1688217 组织和策略问题 0. 不要为小事斤斤计较.(或者说是:知道什么东西不需要标准化) 无需在多个项目或者整个公司范围内强制实施 ...
随机推荐
- 浅谈在Java开发中的枚举的作用和用法
枚举(enum),是指一个经过排序的.被打包成一个单一实体的项列表.一个枚举的实例可以使用枚举项列表中任意单一项的值.枚举在各个语言当中都有着广泛的应用,通常用来表示诸如颜色.方式.类别.状态等等数目 ...
- php中的释放语句unset和释放函数mysql_free_result()
首先要强调的一点是unset在php中已经不再是一个函数了,既然不是函数,那么就没有了返回值,所以用的时候不能够用unset的返回值来做判断. 其次,在函数中,unset只能销毁局部变量,并不能销毁全 ...
- solr4.x之原子更新
solr4.x发布以后,最值得人关注的一个功能,就是原子更新功能,传说的solr是否能真正的做到像数据库一样,支持单列更新呢? 在solr官方的介绍中,原子更新是filed级别的更新,不会涉及整个Do ...
- X86、X64和X86_64区别
x86是指intel的开发的一种32位指令集,从386开始时代开始的,一直沿用至今,是一种cisc指令集,所有intel早期的cpu,amd早期的cpu都支持这种指令集,ntel官方文档里面称 ...
- C_point指针
1,关于C语言中变量的访问方式,直接访问[使用变量名直接引用,操作变量进行赋值,改变变量值等操作],间接访问--指针,一种指向变量飞, 程序对变如量的读写操作,实际是对变量所在的存储空间进行写入和取出 ...
- 50. linux下查看tomcat日志
cd tomcat/logs/ tail -f catalina.out
- openlayers-热地图加载(完整版及代码)
//地圖加載function mapInit(data){ //底图// var raster = new ol.layer.Tile({// source: new ol.source.Stamen ...
- leetcode263
public class Solution { private bool Judge(int x) { ) { return false; } int bound = Convert.ToInt32( ...
- 使用REGINI修改注册表权限
regini regset.ini 就行啦 regset.ini 是你要修改的数据 1.注册表修改 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curr ...
- 前端-BootStrap
bootstrap 英 /'buːtstræp/ 美 /'bʊt'stræp/ n. [计] 引导程序,辅助程序:解靴带 关于 BootCDN BootCDN 是 Bootstrap 中文网支持并维护 ...