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抓即时股票信息
Oct 09 PHP
PHP新手上路(七)
Oct 09 PHP
安装PHP可能遇到的问题“无法载入mysql扩展” 的解决方法
Apr 16 PHP
按上下级层次关系输出内容的PHP代码
Jul 17 PHP
php学习笔记 数组的常用函数
Jun 13 PHP
PHP开发注意事项总结
Feb 04 PHP
php实现专业获取网站SEO信息类实例
Apr 02 PHP
php分页查询mysql结果的base64处理方法示例
May 18 PHP
PHP实现对文件锁进行加锁、解锁操作的方法
Jul 04 PHP
PHP5.6新增加的可变函数参数用法分析
Aug 25 PHP
thinkphp集成前端脚手架Vue-cli的教程图解
Aug 30 PHP
ThinkPHP类似AOP思想的参数验证的实现方法
Dec 18 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
ThinkPHP实现一键清除缓存方法
2014/06/26 PHP
CI框架支持$_GET的两种实现方法
2016/05/18 PHP
Laravel 5+ .env环境配置文件详解
2020/04/06 PHP
判断是否输入完毕再激活提交按钮
2006/06/26 Javascript
JavaScript 拖拉缩放效果
2008/12/10 Javascript
JavaScript Accessor实现说明
2010/12/06 Javascript
页面加载完成后再执行JS的jquery写法以及区别说明
2014/02/22 Javascript
javascript顺序加载图片的方法
2015/07/18 Javascript
谈谈JavaScript中function多重理解
2015/08/28 Javascript
JavaScript的代码编写格式规范指南
2015/12/07 Javascript
三个js循环的关键字示例(for与while)
2016/02/16 Javascript
JavaScript数值千分位格式化的两种简单实现方法
2016/08/01 Javascript
浅谈JavaScript面向对象--继承
2019/03/20 Javascript
nuxt 路由、过渡特效、中间件的实现代码
2020/11/06 Javascript
[01:34:42]NAVI vs EG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
在dataframe两列日期相减并且得到具体的月数实例
2018/07/03 Python
Python提取转移文件夹内所有.jpg文件并查看每一帧的方法
2019/06/27 Python
使用python爬取抖音视频列表信息
2019/07/15 Python
PyCharm最新激活码PyCharm2020.2.3有效
2020/11/18 Python
CSS3制作苹果风格键盘特效
2015/02/26 HTML / CSS
html5实现图片转圈的动画效果——让页面动起来
2017/10/16 HTML / CSS
Laura Mercier官网:彩妆大师罗拉玛斯亚的化妆品牌
2018/01/04 全球购物
zooplus波兰:在线宠物店
2019/07/21 全球购物
德国的各种媒体在线商店:Thalia.de(书籍、电子书、玩具等)
2020/10/08 全球购物
新闻专业推荐信范文
2013/11/20 职场文书
客服文员岗位职责
2013/11/29 职场文书
电子信息工程专业推荐信
2014/02/14 职场文书
高一课前三分钟演讲稿
2014/09/13 职场文书
中韩经贸翻译专业大学生职业生涯规划范文
2014/09/18 职场文书
2014年创卫工作总结
2014/11/24 职场文书
2014年小学安全工作总结
2014/12/04 职场文书
2016年第32个教师节致辞
2015/11/26 职场文书
2019求职信:应届生求职信范文
2019/04/24 职场文书
JavaScript 防篡改对象的用法示例
2021/04/24 Javascript
Spring Cache和EhCache实现缓存管理方式
2021/06/15 Java/Android
sql查询语句之平均分、最高最低分及排序语句
2022/05/30 MySQL