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 相关文章推荐
PHP5 面向对象(学习记录)
Dec 02 PHP
php中使用接口实现工厂设计模式的代码
Jun 17 PHP
ThinkPHP框架实现session跨域问题的解决方法
Jul 01 PHP
ThinkPHP框架安全实现分析
Mar 14 PHP
PHP获取客户端及服务器端IP的封装类
Jul 21 PHP
laravel自定义分页效果
Jul 23 PHP
php 替换文章中的图片路径,下载图片到本地服务器的方法
Feb 06 PHP
PHP5.6.8连接SQL Server 2008 R2数据库常用技巧分析总结
May 06 PHP
使用Laravel中的查询构造器实现增删改查功能
Sep 03 PHP
PHP上传图片到数据库并显示的实例代码
Dec 20 PHP
thinkphp5 框架结合plupload实现图片批量上传功能示例
Apr 04 PHP
如何在PHP中使用AES加密算法加密数据
Jun 24 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
JAVA/JSP学习系列之六
2006/10/09 PHP
php使用Imagick生成图片的方法
2015/07/31 PHP
JavaScript的Function详细
2006/11/14 Javascript
准确获得页面、窗口高度及宽度的JS
2006/11/26 Javascript
setInterval 和 setTimeout会产生内存溢出
2008/02/15 Javascript
使用jQuery内容过滤选择器选择元素实例讲解
2013/04/18 Javascript
jQuery获取CSS样式中的颜色值的问题,不同浏览器格式不同的解决办法
2013/05/13 Javascript
A标签触发onclick事件而不跳转的多种解决方法
2013/06/27 Javascript
JS自动适应的图片弹窗实例
2013/06/29 Javascript
全面介绍javascript实用技巧及单竖杠
2016/07/18 Javascript
走进AngularJs之过滤器(filter)详解
2017/02/17 Javascript
微信小程序授权获取用户详细信息openid的实例详解
2017/09/20 Javascript
AngularJS的$location使用方法详解
2017/10/19 Javascript
Vue.js搭建移动端购物车界面
2020/06/28 Javascript
Node.js实现简单的爬取的示例代码
2019/06/25 Javascript
JS中的算法与数据结构之二叉查找树(Binary Sort Tree)实例详解
2019/08/16 Javascript
初学vue出现空格警告的原因及其解决方案
2019/10/31 Javascript
vue-autoui自匹配webapi的UI控件的实现
2020/03/20 Javascript
python快速排序代码实例
2013/11/21 Python
python用装饰器自动注册Tornado路由详解
2017/02/14 Python
详解如何在python中读写和存储matlab的数据文件(*.mat)
2018/02/24 Python
Python二维码生成识别实例详解
2019/07/16 Python
Python完成哈夫曼树编码过程及原理详解
2019/07/29 Python
利用Opencv实现图片的油画特效实例
2021/02/28 Python
Sam’s Club山姆会员商店:沃尔玛旗下高端会员制商店
2017/01/16 全球购物
Omio葡萄牙:全欧洲低价大巴、火车和航班搜索和比价
2019/02/09 全球购物
标记环网Toke Ring IEEE802.5
2014/05/26 面试题
QA工程师岗位职责
2013/11/20 职场文书
好军嫂事迹材料
2014/01/15 职场文书
学生打架检讨书1000字
2014/01/16 职场文书
总经理助理职责
2014/02/04 职场文书
环保倡议书怎么写
2014/05/16 职场文书
运动会演讲稿300字
2014/08/25 职场文书
最美家庭活动方案
2014/08/31 职场文书
法制教育演讲稿
2014/09/10 职场文书
项目委托协议书(最新)
2014/09/13 职场文书