PHP进程通信基础之信号量与共享内存通信


Posted in PHP onFebruary 19, 2017

由于进程之间谁先执行并不确定,这取决于内核的进程调度算法,其中比较复杂。由此有可能多进程在相同的时间内同时访问共享内存,从而造成不可预料的错误。信号量这个名字起的令人莫名其妙,但是看其英文原意,就十分容易理解。

semaphore 英[ˈseməfɔ:(r)] vt. 发出信号,打旗语;

类似于指挥官的作用。

下面我们看下一个伪代码信号量的使用。

1、创建信号量唯一标识符

$ftok = ftok(__FILE__, 'a');

2、创建信号量资源ID

$sem_resouce_id = sem_get($ftok);

3、接受信号量

sem_acqure($sem_resource_id);

4、释放信号量

sem_release($sem_resource_id);

5、销毁信号量

sem_remove($sem_resource_id);

举个不文雅的例子,使我们容易理解这个信号量在生活中的用法。理解之后可以套用到我们编程领域。
一家公司只有一个卫生间。那么当有人上厕所的时候,都要获取一把锁(信号量),表示卫生间正在使用。代码如下:

sem_acqure($sem_resource_id);

那么员工上完厕所之后,就需要将锁打开,释放锁(信号量),表示现在可以允许别人使用。代码如下:

sem_release($sem_resource_id);

通过一个简单的锁,我们就能够知道当前的厕所(共享内存)是否可以使用。这个例子不雅观,但说明了问题。这篇博客也是有味道的博客,真是不容易。。。。以下是示例代码:

<?php
//创建共享内存区域
$shm_key = ftok(__FILE__, 'a');
$shm_id = shm_attach($shm_key, 1024, 0755);

//var_dump($shm_id);die(); resource(4) of type (sysvshm)
const SHARE_KEY = 1;
$child_list = [];

//加入信号量
$sem_id = ftok(__FILE__, 'b');
$signal = sem_get($sem_id);

//$signal resource(5) of type (sysvsem)


for ($i = 0; $i < 3; $i++) {
  $pid = pcntl_fork();
  if ($pid == -1) {
    exit("Fork fail!".PHP_EOL);
  } elseif ($pid == 0) {
    //获取信号量
    sem_acquire($signal);
    if (shm_has_var($shm_id,SHARE_KEY)) {
      $count = shm_get_var($shm_id, SHARE_KEY);
      $count++;
      //模拟业务处理
      $sec = rand(1, 3);
      sleep($sec);
      shm_put_var($shm_id, SHARE_KEY, $count);
    } else {
      $count = 0;
      $sec = rand(1, 3);
      sleep($sec);
      shm_put_var($shm_id, SHARE_KEY, $count);
    }

    echo "child process: ".getmypid()." is writing! now count is: $count ".PHP_EOL;

    //释放信号量
    sem_release($signal);
    exit("child process".getmypid()."end".PHP_EOL);
  } else {
    $child_list[] = $pid;
  }
}

while (count($child_list) > 0) {
  foreach ($child_list as $key => $pid) {
    $status = pcntl_waitpid($pid, $status);
    if ($status > 0 || $status == -1) {
      unset($child_list[$key]);
    }
  }
  sleep(1);
}

$count = shm_get_var($shm_id, SHARE_KEY);
echo " $count  ".PHP_EOL;

//销毁信号量
sem_remove($signal);

shm_remove($shm_id);
shm_detach($shm_id);
PHP 相关文章推荐
php中chdir()函数用法实例
Nov 13 PHP
php中异常处理方法小结
Jan 09 PHP
使用PHP实现下载CSS文件中的图片
Dec 06 PHP
PHP读取文件内容的五种方式
Dec 28 PHP
Symfony2框架学习笔记之HTTP Cache用法详解
Mar 18 PHP
Yii控制器中操作视图js的方法
Jul 04 PHP
浅谈PHP正则中的捕获组与非捕获组
Jul 18 PHP
PHP自定义递归函数实现数组转JSON功能【支持GBK编码】
Jul 17 PHP
PHP封装的mysqli数据库操作类示例
Feb 16 PHP
PHP实现的杨辉三角求解算法分析
Mar 11 PHP
PHP压缩图片功能的介绍
Mar 21 PHP
Smarty模板语法详解
Jul 20 PHP
PHP进程通信基础之信号
Feb 19 #PHP
PHP 信号管理知识整理汇总
Feb 19 #PHP
php 三大特点:封装,继承,多态
Feb 19 #PHP
PHP实现大数(浮点数)取余的方法
Feb 18 #PHP
Zend Framework基于Command命令行建立ZF项目的方法
Feb 18 #PHP
完美解决php 导出excle的.csv格式的数据时乱码问题
Feb 18 #PHP
Zend Framework数据库操作技巧总结
Feb 18 #PHP
You might like
vs中通过剪切板循环来循环粘贴不同内容
2011/04/30 PHP
PHP 八种基本的数据类型小结
2011/06/01 PHP
需要注意的几个PHP漏洞小结
2012/02/05 PHP
基于php socket(fsockopen)的应用实例分析
2013/06/02 PHP
php实现的统计字数函数定义与使用示例
2017/07/26 PHP
Ajax一统天下之Dojo整合篇
2007/03/24 Javascript
JavaScript中的History历史对象
2008/01/16 Javascript
ExtJS 2.0实用简明教程 之ExtJS版的Hello
2009/04/29 Javascript
jQuery EasyUI API 中文文档 可调整尺寸
2011/09/29 Javascript
jQuery如何实现点击页面获得当前点击元素的id或其他信息
2014/01/09 Javascript
js怎么覆盖原有方法实现重写
2014/09/04 Javascript
jQuery基于xml格式数据实现模糊查询及分页功能的方法
2016/12/25 Javascript
VUE中v-model和v-for指令详解
2017/06/23 Javascript
JavaScript中一些特殊的字符运算
2017/08/17 Javascript
React BootStrap用户体验框架快速上手
2018/03/06 Javascript
微信小程序开发之改变data中数组或对象的某一属性值
2018/07/05 Javascript
解决node-sass偶尔安装失败的方法小结
2018/12/05 Javascript
vue导航栏部分的动态渲染实例
2019/11/01 Javascript
python查找第k小元素代码分享
2013/12/18 Python
python中sys.argv函数精简概括
2018/07/08 Python
Python实现将数据写入netCDF4中的方法示例
2018/08/30 Python
python 使用pandas计算累积求和的方法
2019/02/08 Python
python实现在cmd窗口显示彩色文字
2019/06/24 Python
Python selenium页面加载慢超时的解决方案
2020/03/18 Python
PyQt5连接MySQL及QMYSQL driver not loaded错误解决
2020/04/29 Python
基于python实现简单C/S模式代码实例
2020/09/14 Python
python中四舍五入的正确打开方式
2021/01/18 Python
计算机软件个人的自荐信范文
2013/12/01 职场文书
护理学应聘自荐书范文
2014/02/05 职场文书
经济职业学院毕业生自荐书
2014/03/17 职场文书
2015年纪检监察工作总结
2015/04/08 职场文书
当幸福来敲门英文观后感
2015/06/01 职场文书
导游词之京东大峡谷旅游区
2019/10/29 职场文书
Keras多线程机制与flask多线程冲突的解决方案
2021/05/28 Python
快速学习Oracle触发器和游标
2021/06/30 Oracle
使用ICOM IC-R9500接收机同时测评十台收音机中波接收性能
2022/05/10 无线电