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面试题集锦
Mar 08 PHP
简单的方法让你的后台登录更加安全(php中加session验证)
Aug 22 PHP
ThinkPHP中RBAC类的四种用法分析
Nov 24 PHP
PHP实现的memcache环形队列类实例
Jul 28 PHP
PHP实现补齐关闭的HTML标签
Mar 22 PHP
LINUX下PHP程序实现WORD文件转化为PDF文件的方法
May 13 PHP
php连接oracle数据库的核心步骤
May 26 PHP
php单例模式的简单实现方法
Jun 10 PHP
Yii安装与使用Excel扩展的方法
Jul 13 PHP
php cookie 详解使用实例
Nov 03 PHP
Laravel 5.4重新登录实现跳转到登录前页面的原理和方法
Jul 13 PHP
PHP连接MySQL数据库三种实现方法
Dec 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边学边教》(02.Apache+PHP环境配置――下篇)
2006/12/13 PHP
zf框架db类的分页示例分享
2014/03/14 PHP
微信公众平台开发之配置与请求
2015/08/26 PHP
php多进程应用场景实例详解
2019/07/22 PHP
javaScript call 函数的用法说明
2010/04/09 Javascript
jQuery源码分析之Event事件分析
2010/06/07 Javascript
基于jquery的高性能td和input切换并可修改内容实现代码
2011/01/09 Javascript
JS获取网页图片name属性的方法
2015/04/01 Javascript
javascript类型系统 Window对象学习笔记
2016/01/07 Javascript
jQuery实现从身份证号中获取出生日期和性别的方法分析
2016/02/25 Javascript
AngularJS中的过滤器filter用法完全解析
2016/04/22 Javascript
Backbone View 之间通信的三种方式
2016/08/09 Javascript
Windows环境下npm install 报错: operation not permitted, rename的解决方法
2016/09/26 Javascript
angularjs实现多张图片上传并预览功能
2017/02/24 Javascript
vue上传图片组件编写代码
2017/07/26 Javascript
Vue项目中设置背景图片方法
2018/02/21 Javascript
node.js实现带进度条的多文件上传
2020/03/27 Javascript
Vue2.0 $set()的正确使用详解
2020/07/28 Javascript
JavaScript实现多球运动效果
2020/09/07 Javascript
vue项目中使用rem,在入口文件添加内容操作
2020/11/11 Javascript
Vue router传递参数并解决刷新页面参数丢失问题
2020/12/02 Vue.js
Webpack3+React16代码分割的实现
2021/03/03 Javascript
关于Python中Inf与Nan的判断问题详解
2017/02/08 Python
python使用正则表达式的search()函数实现指定位置搜索功能
2017/11/10 Python
python SocketServer源码深入解读
2019/09/17 Python
翻新二手苹果产品的网络领导者:Mac of all Trades
2017/12/19 全球购物
大学生的自我鉴定范文
2014/01/21 职场文书
法制报告会主持词
2014/04/02 职场文书
施工安全生产承诺书
2014/05/23 职场文书
工作目标责任书
2014/07/23 职场文书
收款委托书范本
2014/09/11 职场文书
2015年女职工工作总结
2015/05/15 职场文书
2016年区委书记抓基层党建工作公开承诺书
2016/03/25 职场文书
python如何利用cv2模块读取显示保存图片
2021/06/04 Python
纯CSS3实现div按照顺序出入效果
2021/07/15 HTML / CSS
MyBatis核心源码深度剖析SQL语句执行过程
2022/05/20 Java/Android