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中的正则表达式函数介绍
Feb 27 PHP
关于crontab的使用详解
Jun 24 PHP
php根据身份证号码计算年龄的实例代码
Jan 18 PHP
Laravel 5 框架入门(一)
Apr 09 PHP
win7安装php框架Yii的方法
Jan 25 PHP
PHP的全局错误处理详解
Apr 25 PHP
PHP实现的限制IP投票程序IP来源分析
May 04 PHP
PHP里面把16进制的图片数据显示在html的img标签上(实现方法)
May 02 PHP
PHP实现电商订单自动确认收货redis队列
May 17 PHP
对于Laravel 5.5核心架构的深入理解
Feb 22 PHP
PHP swoole和redis异步任务实现方法分析
Aug 12 PHP
通过PHP实现用户注册后邮箱验证激活
Nov 10 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的性能
2013/10/30 PHP
Nginx+php配置文件及原理解析
2020/12/09 PHP
JavaScript中的私有/静态属性介绍
2012/07/26 Javascript
Lazy Load 延迟加载图片的jQuery插件中文使用文档
2012/10/18 Javascript
通过上下左右键和回车键切换光标实现代码
2013/03/08 Javascript
下拉列表select 由左边框移动到右边示例
2013/12/04 Javascript
javascript实现随机读取数组的方法
2015/08/03 Javascript
JavaScript实现星级评分
2017/01/12 Javascript
利用CSS、JavaScript及Ajax实现图片预加载的三大方法
2017/01/22 Javascript
jquery.cookie.js的介绍与使用方法
2017/02/09 Javascript
用户管理的设计_jquery的ajax实现二级联动效果
2017/07/13 jQuery
vuex学习之Actions的用法详解
2017/08/29 Javascript
浅谈js的解析顺序 作用域 严格模式
2017/10/23 Javascript
浅谈Vue SPA 首屏加载优化实践
2017/12/15 Javascript
Router解决跨模块下的页面跳转示例
2018/01/11 Javascript
Angular父组件调用子组件的方法
2018/04/02 Javascript
nodejs高大上的部署方式(PM2)
2018/09/11 NodeJs
微信小程序中的canvas 文字断行和省略号显示功能的处理方法
2018/11/14 Javascript
为什么要使用Vuex的介绍
2019/01/19 Javascript
JavaScript实现横版菜单栏
2020/03/17 Javascript
JS寄快递地址智能解析的实现代码
2020/07/16 Javascript
JavaScript实现页面高亮操作提示和蒙板
2021/01/04 Javascript
python实现的简单窗口倒计时界面实例
2015/05/05 Python
Django利用cookie保存用户登录信息的简单实现方法
2019/05/27 Python
numpy.transpose()实现数组的转置例子
2019/12/02 Python
基于python3的socket聊天编程
2020/02/17 Python
python:解析requests返回的response(json格式)说明
2020/04/30 Python
pytorch查看通道数 维数 尺寸大小方式
2020/05/26 Python
基于Pyinstaller打包Python程序并压缩文件大小
2020/05/28 Python
Python timeit模块原理及使用方法
2020/10/10 Python
华为菲律宾官方网站:HUAWEI Philippines
2021/02/23 全球购物
托管代码(Managed Code)和非托管代码(Unmanaged Code)有什么区别
2014/09/29 面试题
青年创业培训欢迎词
2014/01/10 职场文书
2014年审计人员工作总结
2014/12/19 职场文书
幼儿教师三分钟演讲稿
2019/06/21 职场文书
正确使用MySQL INSERT INTO语句
2021/05/26 MySQL