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 解决utf-8和gb2312编码转换问题
Mar 18 PHP
php判断是否为json格式的方法
Mar 04 PHP
destoon复制新模块的方法
Jun 21 PHP
推荐一款PHP+jQuery制作的列表分页的功能模块
Oct 14 PHP
PHP判断来访是搜索引擎蜘蛛还是普通用户的代码小结
Sep 14 PHP
php实现的操作excel类详解
Jan 15 PHP
简单概括PHP的字符串中单引号与双引号的区别
May 07 PHP
php 类中的常量、静态属性、非静态属性的区别
Apr 09 PHP
Laravel如何友好的修改.env配置文件详解
Jun 07 PHP
thinkphp中U方法按路由规则生成url的方法
Mar 12 PHP
PHP操作MongoDB实现增删改查功能【附php7操作MongoDB方法】
Apr 24 PHP
Thinkphp 框架基础之入口文件功能、定义与用法分析
Apr 27 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的十大要点(上)
2009/02/04 PHP
php微信公众开发之获取周边酒店信息的方法
2014/12/22 PHP
php读取远程gzip压缩网页的方法
2014/12/29 PHP
php curl请求信息和返回信息设置代码实例
2015/04/27 PHP
prototype1.4中文手册
2006/09/22 Javascript
js下弹出窗口的变通
2007/04/18 Javascript
ext 列表页面关于多行查询的办法
2010/03/25 Javascript
JQuery之拖拽插件实现代码
2011/04/14 Javascript
js对列表中第一个值处理与jsp页面对列表中第一个值处理的区别详解
2013/11/05 Javascript
JS中attr和prop属性的区别以及优先选择示例介绍
2014/06/30 Javascript
jQuery语法小结(超实用)
2015/12/31 Javascript
jQuery页面刷新(局部、全部)问题分析
2016/01/09 Javascript
BootStrap与validator 使用笔记(JAVA SpringMVC实现)
2016/09/21 Javascript
JS常见疑难点分析之match,charAt,charCodeAt,map,search用法分析
2016/12/25 Javascript
详解vue中组件参数
2018/07/09 Javascript
微信小程序实现左滑修改、删除功能
2020/10/19 Javascript
checkbox在vue中的用法小结
2018/11/13 Javascript
jquery将json转为数据字典的实例代码
2019/10/11 jQuery
Python数据结构与算法之完全树与最小堆实例
2017/12/13 Python
Flask解决跨域的问题示例代码
2018/02/12 Python
python3+PyQt5+Qt Designer实现堆叠窗口部件
2018/04/20 Python
Numpy之将矩阵拉成向量的实例
2019/11/30 Python
PyQt5通过信号实现MVC的示例
2021/02/06 Python
27个经典Linux面试题及答案,你知道几个?
2013/01/10 面试题
学院书画协会部门岗位职责
2013/12/01 职场文书
中层竞聘演讲稿
2014/01/09 职场文书
大学社团活动策划书
2014/01/26 职场文书
运动会稿件200字
2014/02/07 职场文书
竞聘演讲稿精彩开头和结尾
2014/05/14 职场文书
2014年计划生育工作总结
2014/11/14 职场文书
违规违纪检讨书范文
2015/05/06 职场文书
楚门的世界观后感
2015/06/03 职场文书
公务员岗前培训心得体会
2016/01/08 职场文书
python如何在word中存储本地图片
2021/04/07 Python
mysql 获取相邻数据项
2022/05/11 MySQL
Redis主从复制操作和配置详情
2022/09/23 Redis