PHP信号量基本用法实例详解


Posted in PHP onFebruary 12, 2016

本文实例讲述了PHP信号量基本用法。分享给大家供大家参考,具体如下:

一些理论基础:

信号量:又称为信号灯、旗语 用来解决进程(线程同步的问题),类似于一把锁,访问前获取锁(获取不到则等待),访问后释放锁。
临界资源:每次仅允许一个进程访问的资源。
临界区:每个进程中访问临界资源的那段代码叫临界区
进程互斥:两个或以上的进程不能同时进入关于同一组共享变量的临界区域,即一个进程正在访问临界资源,另一个进程要想访问必须等待。
进程同步主要研究如何确定数个进程之间的执行顺序和避免数据竞争的问题 即,如何让多个进程能一块很好的协作运行

举例子:(来自百度百科)

以一个停车场的运作为例。简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆直接进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入外面的一辆进去,如果又离开两辆,则又可以放入两辆,如此往复。

在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是信号量的作用。

$key=ftok(__FILE__,'t');
/**
 * 获取一个信号量资源
 int $key [, int $max_acquire = 1 [, int $perm = 0666 [, int $auto_release = 1 ]]] 
 $max_acquire:最多可以多少个进程同时获取信号
 $perm:权限 默认 0666
 $auto_release:是否自动释放信号量
 */
$sem_id=sem_get($key);
#获取信号
sem_acquire($seg_id);
//do something 这里是一个原子性操作
//释放信号量
sem_release($seg_id);
//把次信号从系统中移除
sem_remove($sem_id);
//可能出现的问题
$fp = sem_get(fileinode(__DIR__), 100);
sem_acquire($fp);
$fp2 = sem_get(fileinode(__DIR__), 1));
sem_acquire($fp2);

Implementation of a read-write semaphore in PHP:

class rw_semaphore {
  const READ_ACCESS = 0;
  const WRITE_ACCESS = 1;  
  /**
   * @access private
   * @var resource - mutex semaphore
   */
  private $mutex;
  /**
   * @access private
   * @var resource - read/write semaphore
   */
  private $resource;
  /**
   * @access private
   * @var int
   */
  private $writers = 0;
  /**
   * @access private
   * @var int
   */
  private $readers = 0;
  /**
   * Default constructor
   * 
   * Initialize the read/write semaphore
   */
  public function __construct() {
    $mutex_key = ftok('/home/cyrus/development/php/sysvipc/rw_semaphore.php', 'm');
    $resource_key = ftok('/home/cyrus/development/php/sysvipc/rw_semaphore.php', 'r');    
    $this->mutex = sem_get($mutex_key, 1);
    $this->resource = sem_get($resource_key, 1);    
  }
  /**
   * Destructor
   * 
   * Remove the read/write semaphore
   */
  public function __destruct() {
    sem_remove($this->mutex);
    sem_remove($this->resource);
  }
  /**
   * Request acess to the resource
   * 
   * @param int $mode
   * @return void
   */
  private function request_access($access_type = self::READ_ACCESS) {  
    if ($access_type == self::WRITE_ACCESS) {
      sem_acquire($this->mutex);
      /* update the writers counter */
      $this->writers++;
      sem_release($this->mutex);      
      sem_acquire($this->resource);
    } else {      
      sem_acquire($this->mutex);      
      if ($this->writers > 0 || $this->readers == 0) {        
        sem_release($this->mutex);        
        sem_acquire($this->resource);        
        sem_acquire($this->mutex);        
      }
      /* update the readers counter */
      $this->readers++;
      sem_release($this->mutex);
    }
  }
  private function request_release($access_type = self::READ_ACCESS) {
    if ($access_type == self::WRITE_ACCESS) {
      sem_acquire($this->mutex);
      /* update the writers counter */
      $this->writers--;
      sem_release($this->mutex);
      sem_release($this->resource);
    } else {
      sem_acquire($this->mutex);
      /* update the readers counter */
      $this->readers--;
      if ($this->readers == 0)
        sem_release($this->resource);
      sem_release($this->mutex);
    }
  }
  /**
   * Request read access to the resource
   * 
   * @return void
   */
  public function read_access() { $this->request_access(self::READ_ACCESS); }
  /**
   * Release read access to the resource
   * 
   * @return void
   */
  public function read_release() { $this->request_release(self::READ_ACCESS); }
  /**
   * Request write access to the resource
   * 
   * @return void
   */
  public function write_access() { $this->request_access(self::WRITE_ACCESS); }
  /**
   * Release write access to the resource
   * 
   * @return void
   */
  public function write_release() { $this->request_release(self::WRITE_ACCESS); }
}

共享内存+信号 实现原子性操作

$SHM_KEY = ftok("/home/joeldg/homeymail/shmtest.php", 'R');
$shmid = sem_get($SHM_KEY, 1024, 0644 | IPC_CREAT);
$data = shm_attach($shmid, 1024);
// we now have our shm segment
// lets place a variable in there
shm_put_var ($data, $inmem, "test");
// now lets get it back. we could be in a forked process and still have
// access to this variable.
printf("shared contents: %s\n", shm_get_var($data, $inmem));
shm_detach($data);

以上列子来源php手册  sem_get 函数comment

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
推荐Discuz!5的PHP代码高亮显示与实现可运行代码
Mar 15 PHP
php中使用cookie来保存用户登录信息的实现代码
Mar 08 PHP
php class中public,private,protected的区别以及实例分析
Jun 18 PHP
PHP错误提示的关闭方法详解
Jun 23 PHP
php用header函数实现301跳转代码实例
Nov 25 PHP
destoon调用自定义模板及样式的公告栏
Jun 21 PHP
php输出xml必须header的解决方法
Oct 17 PHP
PHP面试题之文件目录操作
Oct 15 PHP
PHP微信开发用Cache 解决数据缓存
Jul 11 PHP
ThinkPHP中图片按比例切割的代码实例
Mar 08 PHP
laravel 出现command not found问题的解决方案
Oct 23 PHP
laravel框架实现后台登录、退出功能示例
Oct 31 PHP
PHP消息队列用法实例分析
Feb 12 #PHP
PHP共享内存用法实例分析
Feb 12 #PHP
PHP连接MSSQL方法汇总
Feb 05 #PHP
Symfony2开发之控制器用法实例分析
Feb 05 #PHP
Symfony2实现在doctrine中内置数据的方法
Feb 05 #PHP
PHP MYSQL实现登陆和模糊查询两大功能
Feb 05 #PHP
twig模板获取全局变量的方法
Feb 05 #PHP
You might like
php的curl封装类用法实例
2014/11/07 PHP
分享一段PHP制作的中文拼音首字母工具类
2014/12/11 PHP
php面向对象之反射功能与用法分析
2017/03/29 PHP
PHP获取链表中倒数第K个节点的方法
2018/01/18 PHP
php ajax数据传输和响应方法
2018/08/21 PHP
实例讲解php实现多线程
2019/01/27 PHP
基于jquery的一行代码轻松实现拖动效果
2010/12/28 Javascript
浏览器页面区域大小的js获取方法
2013/09/21 Javascript
JavaScript数据结构和算法之二叉树详解
2015/02/11 Javascript
jQuery实现TAB风格的全国省份城市滑动切换效果代码
2015/08/24 Javascript
详解JavaScript数组和字符串中去除重复值的方法
2016/03/07 Javascript
jquery 属性选择器(匹配具有指定属性的元素)
2016/09/06 Javascript
微信和qq时间格式模板实例详解
2016/10/21 Javascript
js模态对话框使用方法详解
2017/02/16 Javascript
Angular 4依赖注入学习教程之ValueProvider的使用(七)
2017/06/04 Javascript
详解基于webpack2.x的vue2.x的多页面站点
2017/08/21 Javascript
基于 D3.js 绘制动态进度条的实例详解
2018/02/26 Javascript
webpack开发环境和生产环境的深入理解
2018/11/08 Javascript
Vue 实例事件简单示例
2019/09/19 Javascript
vue 指令和过滤器的基本使用(品牌管理案例)
2019/11/04 Javascript
[03:17]2014DOTA2 国际邀请赛中国区预选赛 四强专访
2014/05/23 DOTA
[04:00]黄浦江畔,再会英雄——完美世界DOTA2 TI9应援视频
2019/07/31 DOTA
合并Excel工作薄中成绩表的VBA代码,非常适合教育一线的朋友
2009/04/09 Python
Python os模块中的isfile()和isdir()函数均返回false问题解决方法
2015/02/04 Python
Python基于动态规划算法计算单词距离
2015/07/25 Python
编写Python小程序来统计测试脚本的关键字
2016/03/12 Python
python format 格式化输出方法
2018/07/16 Python
Python使用try except处理程序异常的三种常用方法分析
2018/09/05 Python
CSS3控制HTML元素动画效果
2014/02/08 HTML / CSS
Marriott中国:万豪国际酒店查询预订
2016/09/02 全球购物
校园餐饮创业计划书
2014/01/10 职场文书
高一生物教学反思
2014/01/17 职场文书
高中生班主任评语
2014/04/25 职场文书
工伤事故证明
2014/10/20 职场文书
学校政风行风评议心得体会
2014/10/21 职场文书
英文感谢信范文
2015/01/21 职场文书