PHP进程通信基础之信号量与共享内存通信

 更新时间:2017年02月19日 10:17:11   投稿:hebedich  
这篇文章主要介绍了PHP进程通信基础知识中的信号量与共享内存通信的相关资料,有需要的小伙伴可以查看下

由于进程之间谁先执行并不确定,这取决于内核的进程调度算法,其中比较复杂。由此有可能多进程在相同的时间内同时访问共享内存,从而造成不可预料的错误。信号量这个名字起的令人莫名其妙,但是看其英文原意,就十分容易理解。

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面向对象之多态

    这篇文章主要介绍了实例讲解PHP面向对象之多态,本文用实例讲解什么情况下使用PHP的多态、多态的好处等内容,可以充分帮你理解多态,需要的朋友可以参考下
    2014-08-08
  • php debug 安装技巧

    php debug 安装技巧

    软件开发的断点调试是必不可少,这里介绍ubuntu10.04中eclipse工具中php的调试配置。
    2011-04-04
  • php数据类型判断函数有哪些

    php数据类型判断函数有哪些

    php数据类型判断时需要注意的是is_numeric() 检测变量是否为数字或数字字符串有别 is_integer()
    2013-09-09
  • PHP简单获取及判断提交来源的方法

    PHP简单获取及判断提交来源的方法

    这篇文章主要介绍了PHP简单获取及判断提交来源的方法,涉及PHP中$_SERVER及字符串操作的使用技巧,需要的朋友可以参考下
    2016-04-04
  • PHP生成器(generator)和协程的实现方法详解

    PHP生成器(generator)和协程的实现方法详解

    这篇文章主要介绍了PHP生成器(generator)和协程的实现方法,结合实例形式详细分析了php生成器以及由此延伸出来的协程相关操作技巧与注意事项,需要的朋友可以参考下
    2018-07-07
  • 探寻PHP脚本不报错的原因

    探寻PHP脚本不报错的原因

    PHP程序错误一般有三种:语法错误,运行时错误,逻辑错误。
    2014-06-06
  • PHP高精确度运算BC函数库实例详解

    PHP高精确度运算BC函数库实例详解

    这篇文章主要介绍了PHP高精确度运算BC函数库,结合实例形式分析了BC函数库中bccomp、bcadd、bcsub、bcmod、bcdiv、bcmul等函数的功能以及高精度数学运算使用方法,需要的朋友可以参考下
    2017-08-08
  • php处理斐波那契数列非递归方法

    php处理斐波那契数列非递归方法

    phpchina上有个名人叫大白菜心,经常会拿这个事来说事。传统处理会把斐波那契数列用递归来处理,效率慢是必然的。不过他说事说吧,居然不拿出答案来,就有点不厚道了
    2012-02-02
  • PHP正则替换函数preg_replace和preg_replace_callback使用总结

    PHP正则替换函数preg_replace和preg_replace_callback使用总结

    这篇文章主要介绍了PHP正则替换函数preg_replace和preg_replace_callback使用总结,本文是在写一个模板引擎遇到一个特殊需求时总结而来,需要的朋友可以参考下
    2014-09-09
  • mysq GBKl乱码

    mysq GBKl乱码

    mysq GBKl乱码...
    2006-11-11

最新评论