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连接Oracle数据库
Oct 09 PHP
PHP文件上传实例详解!!!
Jan 02 PHP
PHP 输出简单动态WAP页面
Jun 09 PHP
PHP 一个页面执行时间类代码
Mar 05 PHP
深入解析yii权限分级式访问控制的实现(非RBAC法)
Jun 13 PHP
php中error与exception的区别及应用
Jul 28 PHP
Windows下安装PHP单元测试环境PHPUnit图文教程
Oct 24 PHP
thinkphp模板用法和内容输出实例
Nov 28 PHP
给ECShop添加最新评论
Jan 07 PHP
PHP版微信公众平台红包API
Apr 02 PHP
PHP技术开发微信公众平台
Jul 22 PHP
YII视图整合kindeditor扩展的方法
Jul 13 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 分页类(模仿google)-面试题目解答
2009/09/13 PHP
PHP Curl出现403错误的解决办法
2014/05/29 PHP
php+mysqli使用面向对象方式查询数据库实例
2015/01/29 PHP
PHP实现从远程下载文件的方法
2015/03/12 PHP
php实现购物车产品删除功能(2)
2020/07/23 PHP
php封装的mongodb操作类代码
2017/08/06 PHP
JavaScript 学习笔记(十六) js事件
2010/02/01 Javascript
javascript showModalDialog 内跳转页面的问题
2010/11/25 Javascript
javascript基础知识大集锦(一) 推荐收藏
2011/01/13 Javascript
jQuery中获取Radio元素值的方法
2013/07/02 Javascript
javascript 弹出的窗口返回值给父窗口具体实现
2013/11/23 Javascript
JavaScript中判断整字类型最简洁的实现方法
2014/11/08 Javascript
不同编码的页面表单数据乱码问题解决方法
2015/02/15 Javascript
JavaScript+html5 canvas制作的圆中圆效果实例
2016/01/27 Javascript
详解javascript 正则表达式之分组与前瞻匹配
2018/05/30 Javascript
Vue 子组件与数据传递问题及注意事项
2019/07/11 Javascript
Layui动态生成select下拉选择框不显示的解决方法
2019/09/24 Javascript
[01:51]2014DOTA2西雅图邀请赛 MVP 外卡赛black场间采访
2014/07/09 DOTA
python网络编程实例简析
2014/09/26 Python
python实现指定字符串补全空格的方法
2015/04/30 Python
python基于urllib实现按照百度音乐分类下载mp3的方法
2015/05/25 Python
Python fileinput模块使用实例
2015/06/03 Python
np.dot()函数的用法详解
2020/01/17 Python
基于nexus3配置Python仓库过程详解
2020/06/15 Python
浅谈keras 的抽象后端(from keras import backend as K)
2020/06/16 Python
Python面向对象多态实现原理及代码实例
2020/09/16 Python
使用CSS实现阅读进度条
2017/02/27 HTML / CSS
北京SQL新华信咨询
2016/09/30 面试题
公司端午节活动方案
2014/02/04 职场文书
市场营销方案范文
2014/03/11 职场文书
应届硕士毕业生自荐信
2014/05/26 职场文书
民间借贷借条范本
2015/05/25 职场文书
公司要求试用期员工提交“述职报告”,该怎么写?
2019/07/17 职场文书
python3实现Dijkstra算法最短路径的实现
2021/05/12 Python
python树莓派通过队列实现进程交互的程序分析
2021/07/04 Python
微软Win11什么功能最惊艳? Windows11新功能特性汇总
2021/11/21 数码科技