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+apc实现上传进度条且在IE7下不显示的问题解决方法
Apr 25 PHP
ThinkPHP验证码使用简明教程
Mar 05 PHP
PHP中的Memcache详解
Apr 05 PHP
php去除字符串中空字符的常用方法小结
Mar 17 PHP
PHP实现对数组分页处理实例详解
Feb 07 PHP
Yii2学习笔记之汉化yii设置表单的描述(属性标签attributeLabels)
Feb 07 PHP
phpStudy2016 配置多个域名期间遇到的问题小结
Oct 19 PHP
PHP基于cookie实现统计在线人数功能示例
Jan 16 PHP
简单实用的PHP文本缓存类实例
Mar 22 PHP
php传值和传引用的区别点总结
Nov 19 PHP
如何在Laravel5.8中正确地应用Repository设计模式
Nov 26 PHP
PHP使用PDO实现mysql防注入功能详解
Dec 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
PHP学习笔记之一
2011/01/17 PHP
discuz免激活同步登入代码修改方法(discuz同步登录)
2013/12/24 PHP
php车辆违章查询数据示例
2016/10/14 PHP
基于PHP的加载类操作以及其他两种魔术方法的应用实例
2017/08/28 PHP
javascript contains和compareDocumentPosition 方法来确定是否HTML节点间的关系
2010/02/04 Javascript
js 为label标签和div标签赋值的方法
2013/08/08 Javascript
用JS将搜索的关键字高亮显示实现代码
2013/11/08 Javascript
js调试系列 断点与动态调试[基础篇]
2014/06/18 Javascript
asp.net+jquery.form实现图片异步上传的方法(附jquery.form.js下载)
2016/05/05 Javascript
深入理解jQuery中的事件冒泡
2016/05/24 Javascript
谈谈第三方App接入微信登录 解读
2016/12/27 Javascript
Vue.js父与子组件之间传参示例
2017/02/28 Javascript
angular学习之从零搭建一个angular4.0项目
2017/07/10 Javascript
js编写简单的计时器功能
2017/07/15 Javascript
详解mpvue开发小程序小总结
2018/07/25 Javascript
解决layui前端框架 form表单,table表等内置控件不显示的问题
2018/08/19 Javascript
vue实现搜索过滤效果
2019/05/28 Javascript
python中安装模块包版本冲突问题的解决
2017/05/02 Python
Django学习笔记之ORM基础教程
2018/03/27 Python
python学习笔记--将python源文件打包成exe文件(pyinstaller)
2018/05/26 Python
使用anaconda的pip安装第三方python包的操作步骤
2018/06/11 Python
python实现简单tftp(基于udp协议)
2018/07/30 Python
pygame实现简易飞机大战
2018/09/11 Python
详解Python解决抓取内容乱码问题(decode和encode解码)
2019/03/29 Python
pandas 对日期类型数据的处理方法详解
2019/08/08 Python
Python 依赖库太多了该如何管理
2019/11/08 Python
基于django micro搭建网站实现加水印功能
2020/05/22 Python
办公室副主任职责范本
2014/03/08 职场文书
学生期末评语大全
2014/04/30 职场文书
员工安全生产承诺书
2014/05/22 职场文书
1000字打架检讨书
2014/11/03 职场文书
生产现场禁烟通知
2015/04/23 职场文书
农村婚礼司仪主持词
2015/06/29 职场文书
2015年防灾减灾工作总结
2015/07/24 职场文书
golang 生成对应的数据表struct定义操作
2021/04/28 Golang
Java版 单机五子棋
2022/05/04 Java/Android