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 相关文章推荐
apache+mysql+php+ssl服务器之完全安装攻略
Sep 05 PHP
纯真IP数据库的应用 IP地址转化成十进制
Jun 14 PHP
php定时计划任务与fsockopen持续进程实例
May 23 PHP
CodeIgniter采用config控制的多语言实现根据浏览器语言自动转换功能
Jul 18 PHP
PHP产生不重复随机数的5个方法总结
Nov 12 PHP
PHP使用pcntl_fork实现多进程下载图片的方法
Dec 16 PHP
php对关联数组循环遍历的实现方法
Mar 13 PHP
PHP代码实现表单数据验证类
Jul 28 PHP
为你总结一些php系统类函数
Oct 21 PHP
PHP序列化的四种实现方法与横向对比
Nov 29 PHP
php json转换相关知识(小结)
Dec 21 PHP
PHP 结合 Boostrap 结合 js 实现学生列表删除编辑及搜索功能
May 21 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 编程请选择正确的文本编辑软件
2006/12/21 PHP
PHP输出缓存ob系列函数详解
2014/03/11 PHP
Yii2 批量插入、更新数据实例
2017/03/15 PHP
php表单习惯用的正则表达式
2017/10/11 PHP
发布一个高效的JavaScript分析、压缩工具 JavaScript Analyser
2007/11/30 Javascript
Javascript Function对象扩展之延时执行函数
2010/07/06 Javascript
Javascript面象对象成员、共享成员变量实验
2010/11/19 Javascript
js实现连续英文字符自动换行兼容ie6 ie7和firefox
2013/09/06 Javascript
IE的事件传递-event.cancelBubble示例介绍
2014/01/12 Javascript
js实现横向百叶窗效果网页切换动画效果的方法
2015/03/02 Javascript
Jquery为DIV添加click事件的简单实例
2016/06/02 Javascript
使用Promise链式调用解决多个异步回调的问题
2017/01/15 Javascript
easy ui datagrid 从编辑框中获取值的方法
2017/02/22 Javascript
Vue.js手风琴菜单组件开发实例
2017/05/16 Javascript
ES6入门教程之let和const命令详解
2017/05/17 Javascript
详解vue移动端项目代码拆分记录
2019/03/15 Javascript
使用webpack搭建vue环境的教程详解
2019/12/31 Javascript
vue学习笔记之slot插槽用法实例分析
2020/02/29 Javascript
解决vue单页面多个组件嵌套监听浏览器窗口变化问题
2020/07/30 Javascript
vue-cli单页面预渲染seo-prerender-spa-plugin操作
2020/08/10 Javascript
[05:05]DOTA2亚洲邀请赛 战队出场仪式
2015/02/07 DOTA
Python基于xlrd模块操作Excel的方法示例
2018/06/21 Python
python合并已经存在的sheet数据到新sheet的方法
2018/12/11 Python
Django框架使用内置方法实现登录功能详解
2019/06/12 Python
基于Django signals 信号作用及用法详解
2020/03/28 Python
Python PyQt5运行程序把输出信息展示到GUI图形界面上
2020/04/27 Python
sklearn的predict_proba使用说明
2020/06/28 Python
基于tensorflow for循环 while循环案例
2020/06/30 Python
Python的3种运行方式:命令行窗口、Python解释器、IDLE的实现
2020/10/10 Python
国贸类专业毕业生的求职信分享
2013/12/08 职场文书
培训楼经理岗位责任制
2014/02/10 职场文书
草房子读书笔记
2015/06/29 职场文书
中国梦党课学习心得体会
2016/01/05 职场文书
2016年教师师德师风心得体会
2016/01/12 职场文书
2019关于实习生工作安排及待遇的管理方案!
2019/07/16 职场文书
深入浅析Django MTV模式
2021/09/04 Python