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 相关文章推荐
NT IIS下用ODBC连接数据库
Oct 09 PHP
Discuz 5.0 中读取纯真IP数据库函数分析
Mar 16 PHP
mysql_fetch_row,mysql_fetch_array,mysql_fetch_assoc的区别
Apr 24 PHP
有关PHP中MVC的开发经验分享
May 17 PHP
Zend Framework页面缓存实例
Jun 25 PHP
qq登录,新浪微博登录接口申请过程中遇到的问题
Jul 22 PHP
PHP图片处理之使用imagecopy函数添加图片水印实例
Nov 19 PHP
PHP中Http协议post请求参数
Nov 02 PHP
YII Framework教程之异常处理详解
Mar 14 PHP
SSO单点登录的PHP实现方法(Laravel框架)
Mar 23 PHP
mysql_escape_string()函数用法分析
Apr 25 PHP
laravel 判断查询数据库返回值的例子
Oct 11 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 is_file()和is_dir()用于遍历目录时用法注意事项
2010/03/02 PHP
php数据结构 算法(PHP描述) 简单选择排序 simple selection sort
2011/08/09 PHP
Could not load type System.ServiceModel.Activation.HttpModule解决办法
2012/12/29 PHP
smarty模板引擎之内建函数用法
2015/03/30 PHP
利用PHPExcel实现Excel文件的写入和读取
2017/04/26 PHP
jquery插件开发方法(初学者)
2012/02/03 Javascript
利用谷歌地图API获取点与点的距离的js代码
2012/10/11 Javascript
js 获取后台的字段 改变 checkbox的被选中的状态 代码
2013/06/05 Javascript
js获取当前页面的url网址信息
2014/06/12 Javascript
浅谈Jquery为元素绑定事件
2015/04/27 Javascript
在JavaScript中处理数组之reverse()方法的使用
2015/06/09 Javascript
jQuery Mobile 和 Kendo UI 的比较
2016/05/05 Javascript
jQuery实现左侧导航模块的显示与隐藏效果
2016/07/04 Javascript
jQuery实现点击任意位置弹出层外关闭弹出层效果
2016/10/19 Javascript
DOM 事件的深入浅出(二)
2016/12/05 Javascript
jQuery实现点击DIV同时点击CheckBox,并为DIV上背景色的实例
2017/12/18 jQuery
webpack多入口文件页面打包配置详解
2018/01/09 Javascript
webpack-url-loader 解决项目中图片打包路径问题
2019/02/15 Javascript
[56:18]VGJ.S vs Secret 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python中max函数用于二维列表的实例
2018/04/03 Python
Numpy中的mask的使用
2018/07/21 Python
Python利用递归实现文件的复制方法
2018/10/27 Python
python selenium 弹出框处理的实现
2019/02/26 Python
Python中的 is 和 == 以及字符串驻留机制详解
2019/06/28 Python
python 将字符串中的数字相加求和的实现
2019/07/18 Python
python常用数据重复项处理方法
2019/11/22 Python
python中如何使用虚拟环境
2020/10/14 Python
Python常用GUI框架原理解析汇总
2020/12/07 Python
带有css3动画效果的兼容多浏览器简单导航条示例
2014/01/26 HTML / CSS
css3+jq创作含苞待放的荷花
2014/02/20 HTML / CSS
html5 input元素新特性_动力节点Java学院整理
2017/07/06 HTML / CSS
HTML5 Canvas中使用路径描画二阶、三阶贝塞尔曲线
2015/01/01 HTML / CSS
计算机专业求职信
2014/06/02 职场文书
行政主管岗位职责范本
2015/04/09 职场文书
Python基础之常用库常用方法整理
2021/04/30 Python
Win11快速关闭所有广告推荐
2022/04/19 数码科技