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 相关文章推荐
mac下使用brew配置环境的步骤分享
May 23 PHP
PHP实现时间轴函数代码
Oct 08 PHP
PHP读取txt文件的内容并赋值给数组的代码
Nov 03 PHP
PHP处理Oracle的CLOB实例
Nov 03 PHP
PHP使用CURL模拟登录的方法
Jul 08 PHP
WordPress中Gravatar头像缓存到本地及相关优化的技巧
Dec 19 PHP
Zend Framework动作助手Redirector用法实例详解
Mar 05 PHP
php+ajax登录跳转登录实现思路
Jul 31 PHP
利用php生成验证码
Feb 23 PHP
Yii2表单事件之Ajax提交实现方法
May 04 PHP
php异常处理捕获错误整理
Sep 23 PHP
laravel实现图片上传预览,及编辑时可更换图片,并实时变化的例子
Nov 14 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中cookie的作用域
2008/03/27 PHP
PHP动态分页函数,PHP开发分页必备啦
2011/11/07 PHP
php gzip压缩输出的实现方法
2013/04/27 PHP
Yii框架自定义数据库操作组件示例
2019/11/11 PHP
PHP 对象继承原理与简单用法示例
2020/04/21 PHP
ExtJs的Date格式字符代码
2010/12/30 Javascript
jquery中ajax调用json数据的使用说明
2011/03/17 Javascript
jQuery过滤HTML标签并高亮显示关键字的方法
2015/08/07 Javascript
jQuery EasyUi实战教程之布局篇
2016/01/26 Javascript
js将滚动条滚动到指定位置的简单实现方法
2016/06/25 Javascript
Laravel中常见的错误与解决方法小结
2016/08/30 Javascript
jQuery实现动态添加tr到table的方法
2016/12/26 Javascript
理解javascript中的闭包
2017/01/11 Javascript
原生js实现电商侧边导航效果
2017/01/19 Javascript
angular4实现tab栏切换的方法示例
2017/10/21 Javascript
详解使用React全家桶搭建一个后台管理系统
2017/11/04 Javascript
Vue axios全局拦截 get请求、post请求、配置请求的实例代码
2018/11/28 Javascript
详解如何在Javascript和Sass之间共享变量
2019/11/13 Javascript
[01:00]一分钟回顾2018DOTA2亚洲邀请赛现场活动
2018/04/07 DOTA
详解python中requirements.txt的一切
2017/03/03 Python
在python3环境下的Django中使用MySQL数据库的实例
2017/08/29 Python
python之消除前缀重命名的方法
2018/10/21 Python
在加拿大在线租赁和购买电子游戏:Game Access
2019/09/02 全球购物
团员个人的自我评价
2013/12/02 职场文书
会计应届生的自荐信
2013/12/13 职场文书
学习自我鉴定
2014/02/01 职场文书
药品营销策划方案
2014/06/15 职场文书
俄语专业毕业生求职信
2014/07/12 职场文书
2014年销售内勤工作总结
2014/12/01 职场文书
安全员岗位职责范本
2015/04/11 职场文书
2015年教研组工作总结
2015/05/04 职场文书
2016中考冲刺决心书
2015/09/22 职场文书
《围炉夜话》110句人生箴言,精辟有内涵,引人深思
2019/10/23 职场文书
Python实现老照片修复之上色小技巧
2021/10/16 Python
MySQL索引失效场景及解决方案
2022/07/23 MySQL
详解MySQL的内连接和外连接
2023/05/08 MySQL