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 Socket 编程
Apr 09 PHP
php数组函数序列之array_unique() - 去除数组中重复的元素值
Oct 29 PHP
php 如何获取数组第一个值
Aug 06 PHP
php分页函数示例代码分享
Feb 24 PHP
可以保证单词完整性的PHP英文字符串截取代码分享
Jul 15 PHP
php实现获取及设置用户访问页面语言类
Sep 24 PHP
PHP提高编程效率的20个要点
Sep 23 PHP
分享3个php获取日历的函数
Sep 25 PHP
PHP MVC框架路由学习笔记
Mar 02 PHP
用HTML/JS/PHP方式实现页面延时跳转的简单实例
Jul 18 PHP
PHP常用的类封装小结【4个工具类】
Jun 28 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导出Word文档的原理和实例
2013/10/21 PHP
ThinkPHP的I方法使用详解
2014/06/18 PHP
ThinkPHP CURD方法之where方法详解
2014/06/18 PHP
php学习笔记之基础知识
2014/11/08 PHP
php使用ffmpeg向视频中添加文字字幕的实现方法
2016/05/23 PHP
PHP简单判断手机设备的方法
2016/08/23 PHP
Yii 2.0自带的验证码使用经验分享
2017/06/19 PHP
PHP错误提示It is not safe to rely on the system……的解决方法
2019/03/25 PHP
JQuery 常用方法基础教程
2009/02/06 Javascript
fancybox1.3.1 基于Jquery的插件在IE中图片显示问题
2010/10/01 Javascript
Egret引擎开发指南之发布项目
2014/09/03 Javascript
javascript trim函数在IE下不能用的解决方法
2014/09/12 Javascript
超链接怎么正确调用javascript函数
2016/05/23 Javascript
JS小数运算出现多为小数问题的解决方法
2016/06/02 Javascript
canvas实现流星雨的背景效果
2017/01/13 Javascript
Angular2使用vscode断点调试ts文件的方法
2017/12/13 Javascript
微信小程序sessionid不一致问题解决
2019/08/30 Javascript
BootstrapValidator实现表单验证功能
2019/11/08 Javascript
vue-admin-template配置快捷导航的代码(标签导航栏)
2020/09/04 Javascript
[28:07]完美世界DOTA2联赛PWL S3 Phoenix vs INK ICE 第二场 12.13
2020/12/17 DOTA
python中文分词,使用结巴分词对python进行分词(实例讲解)
2017/11/14 Python
在python3.5中使用OpenCV的实例讲解
2018/04/02 Python
Python中出现IndentationError:unindent does not match any outer indentation level错误的解决方法
2020/04/18 Python
使用pycharm设置控制台不换行的操作方法
2019/01/19 Python
python的slice notation的特殊用法详解
2019/12/27 Python
HTML5实现动画效果的方式汇总
2016/02/29 HTML / CSS
教学个人的自我评价分享
2014/02/16 职场文书
合作经营协议书
2014/04/17 职场文书
代理协议书
2014/04/22 职场文书
安全生产月演讲稿
2014/05/09 职场文书
售后服务承诺书模板
2014/05/21 职场文书
2014年财务部工作总结
2014/11/11 职场文书
2015年超市工作总结范文
2015/05/26 职场文书
演讲稿之感恩老师(三篇范文)
2019/09/06 职场文书
Python数据清洗工具之Numpy的基本操作
2021/04/22 Python
Python中OpenCV实现查找轮廓的实例
2021/06/08 Python