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 管理系统程序中的后门
Aug 05 PHP
php 转换字符串编码 iconv与mb_convert_encoding的区别说明
Nov 10 PHP
php中存储用户ID和密码到mysql数据库的方法
Feb 06 PHP
如何修改和添加Apache的默认站点目录
Jul 05 PHP
PHP设计模式之观察者模式(Observer)详细介绍和代码实例
Apr 08 PHP
php中json_encode UTF-8中文乱码的更好解决方法
Sep 28 PHP
php检测apache mod_rewrite模块是否安装的方法
Mar 14 PHP
php生成二维码图片方法汇总
Dec 17 PHP
thinkPHP框架实现多表查询的方法
Jun 14 PHP
PHP通过文件路径获取文件名的实例代码
Oct 14 PHP
php面试实现反射注入的详细方法
Sep 30 PHP
PHPStorm2020.1永久激活及下载更新至2020(推荐)
Sep 25 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
PHP实现把文本中的URL转换为链接的auolink()函数分享
2014/07/29 PHP
PHP实现的简单异常处理类示例
2017/05/04 PHP
Laravel相关的一些故障解决
2020/08/19 PHP
TNC vs BOOM BO3 第三场2.13
2021/03/10 DOTA
jquery的Theme和Theme Switcher使用小结
2010/09/08 Javascript
HTML页面滚动时获取离页面顶部的距离2种实现方法
2013/09/05 Javascript
js中一个函数获取另一个函数返回值问题探讨
2013/11/21 Javascript
使用js判断数组中是否包含某一元素(类似于php中的in_array())
2013/12/12 Javascript
Jquery Ajax解析XML数据(同步及异步调用)简单实例
2014/02/12 Javascript
jQuery实现仿路边灯箱广告图片轮播效果
2015/04/15 Javascript
jQuery中ajax的load()与post()方法实例详解
2016/01/05 Javascript
js判断图片加载完成后获取图片实际宽高的方法
2016/02/25 Javascript
JSON与JS对象的区别与对比
2017/03/01 Javascript
javascript编写简易计算器
2017/05/06 Javascript
Vue.js常用指令之循环使用v-for指令教程
2017/06/27 Javascript
深入浅析Vue.js中 computed和methods不同机制
2018/03/22 Javascript
jQuery实现常见的隐藏与展示列表效果示例
2018/06/04 jQuery
vue.js绑定事件监听器示例【基于v-on事件绑定】
2018/07/07 Javascript
vue解决使用$http获取数据时报错的问题
2019/10/30 Javascript
浅谈实现在线预览PDF的几种解决办法
2020/08/10 Javascript
[11:44]Ti9 OG夺冠时刻
2019/08/25 DOTA
把MySQL表结构映射为Python中的对象的教程
2015/04/07 Python
python中range()与xrange()用法分析
2016/09/21 Python
使用Python制作简单的小程序IP查看器功能
2019/04/16 Python
python3图片文件批量重命名处理
2019/10/31 Python
用OpenCV将视频分解成单帧图片,图片合成视频示例
2019/12/10 Python
解决pycharm同一目录下无法import其他文件
2020/02/12 Python
jurlique茱莉蔻英国官网:澳洲天然护肤品
2018/08/03 全球购物
意大利单身交友网站:Meetic
2020/07/12 全球购物
《风筝》教学反思
2014/04/10 职场文书
文明工地标语
2014/06/16 职场文书
十佳标兵事迹材料
2014/08/18 职场文书
工作失职检讨书500字
2014/10/17 职场文书
关于拾金不昧的感谢信
2015/01/21 职场文书
博士给导师的自荐信
2015/03/06 职场文书
Python基于百度API识别并提取图片中文字
2021/06/27 Python