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 相关文章推荐
PHP 判断常量,变量和函数是否存在
Apr 26 PHP
php面向对象全攻略 (二) 实例化对象 使用对象成员
Sep 30 PHP
ajax完美实现两个网页 分页功能的实例代码
Apr 16 PHP
php一次性删除前台checkbox多选内容的方法
Sep 22 PHP
php不允许用户提交空表单(php空值判断)
Nov 12 PHP
php计算两个日期相差天数的方法
Mar 14 PHP
PHP文件上传之多文件上传的实现思路
Jan 27 PHP
PHP单态模式简单用法示例
Nov 16 PHP
php版阿里大于(阿里大鱼)短信发送实例详解
Nov 30 PHP
PHP长网址与短网址的实现方法
Oct 13 PHP
php+redis消息队列实现抢购功能
Feb 08 PHP
php转换上传word文件为PDF的方法【基于COM组件】
Jun 10 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中的生成XML文件的4种方法分享
2012/10/06 PHP
PHP的pcntl多进程用法实例
2015/03/19 PHP
WordPress中创建用户角色的相关PHP函数使用详解
2015/12/25 PHP
PHP实现163邮箱自动发送邮件
2016/03/29 PHP
Centos PHP 扩展Xchche的安装教程
2016/07/09 PHP
PHP使用栈解决约瑟夫环问题算法示例
2017/08/27 PHP
自己的js工具_Form 封装
2009/08/21 Javascript
基于jquery的滚动条滚动固定div(附演示下载)
2012/10/29 Javascript
jquery遍历筛选数组的几种方法和遍历解析json对象
2013/12/13 Javascript
javascript实现数组中的内容随机输出
2015/08/11 Javascript
JS正则表达式验证账号、手机号、电话和邮箱是否合法
2017/03/08 Javascript
Angular使用$http.jsonp发送跨站请求的方法
2017/03/16 Javascript
详解Vue中添加过渡效果
2017/03/20 Javascript
浅谈PDF.js使用心得
2018/06/07 Javascript
vue 解决在微信内置浏览器中调用支付宝支付的情况
2020/11/09 Javascript
Python 字典dict使用介绍
2014/11/30 Python
用实例分析Python中method的参数传递过程
2015/04/02 Python
python实现在sqlite动态创建表的方法
2015/05/08 Python
Django开发中复选框用法示例
2018/03/20 Python
解决pycharm界面不能显示中文的问题
2018/05/23 Python
python 获取毫秒数,计算调用时长的方法
2019/02/20 Python
python 将有序数组转换为二叉树的方法
2019/03/26 Python
matplotlib jupyter notebook 图像可视化 plt show操作
2020/04/24 Python
HTML5页面中尝试调起APP功能
2017/09/12 HTML / CSS
2014年高三毕业生自我评价
2014/01/11 职场文书
五年级科学教学反思
2014/02/05 职场文书
护士岗前培训自我评鉴
2014/02/28 职场文书
班级口号大全
2014/06/09 职场文书
生活部的活动方案
2014/08/19 职场文书
2014年个人技术工作总结
2014/12/08 职场文书
工程部主管岗位职责
2015/02/12 职场文书
保护校园环境倡议书
2015/04/28 职场文书
ES6 解构赋值的原理及运用
2021/05/25 Javascript
详解Python为什么不用设计模式
2021/06/24 Python
SQL优化老出错,那是你没弄明白MySQL解释计划用法
2021/11/27 MySQL
Python实现学生管理系统并生成exe可执行文件详解流程
2022/01/22 Python