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编实现程动态图像的创建代码
Sep 28 PHP
mysql下创建字段并设置主键的php代码
May 16 PHP
PHP运行时强制显示出错信息的代码
Apr 20 PHP
深入apache host的配置详解
Jun 09 PHP
解析:使用php mongodb扩展时 需要注意的事项
Jun 18 PHP
php多层数组与对象的转换实例代码
Aug 05 PHP
PHP图片自动裁切应付不同尺寸的显示
Oct 16 PHP
php简单实现无限分类树形列表的方法
Mar 27 PHP
PHP查找与搜索数组元素方法总结
Jun 12 PHP
php获取当前月与上个月月初及月末时间戳的方法
Dec 05 PHP
PHP将整数数字转换为罗马数字实例分享
Mar 17 PHP
thinkphp框架类库扩展操作示例
Nov 26 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
拼音码表的生成
2006/10/09 PHP
php 文件夹删除、php清除缓存程序
2009/08/25 PHP
在IIS7.0下面配置PHP 5.3.2运行环境的方法
2010/04/13 PHP
php中批量修改文件后缀名的函数代码
2011/10/23 PHP
基于递归实现的php树形菜单代码
2014/11/19 PHP
PHP获取数组最后一个值的2种方法
2015/01/21 PHP
PHP常用日期加减计算方法实例小结
2018/07/31 PHP
巧用js提交表单轻松解决一个页面有多个提交按钮
2013/11/17 Javascript
javascript文本框内输入文字倒计数的方法
2015/02/24 Javascript
浅析ES6的八进制与二进制整数字面量
2016/08/30 Javascript
jstree单选功能的实现方法
2017/06/07 Javascript
Vue+webpack项目配置便于维护的目录结构教程详解
2018/10/14 Javascript
Vue 子组件与数据传递问题及注意事项
2019/07/11 Javascript
layui实现下拉框三级联动
2019/07/26 Javascript
vue实现员工信息录入功能
2020/06/11 Javascript
微信小程序实现身份证取景框拍摄
2020/09/09 Javascript
[03:18]DOTA2亚洲邀请赛小组赛第一日 RECAP赛事回顾
2015/01/30 DOTA
[00:31]DOTA2荣耀之路7:Miracle-空血无敌斩
2018/05/31 DOTA
Python序列操作之进阶篇
2016/12/08 Python
python中利用Future对象回调别的函数示例代码
2017/09/07 Python
python的Crypto模块实现AES加密实例代码
2018/01/22 Python
python使用RNN实现文本分类
2018/05/24 Python
Python从ZabbixAPI获取信息及实现Zabbix-API 监控的方法
2018/09/17 Python
python bmp转换为jpg 并删除原图的方法
2018/10/25 Python
python随机生成大小写字母数字混合密码(仅20行代码)
2020/02/01 Python
python如何判断IP地址合法性
2020/04/05 Python
Tensorflow tf.nn.depthwise_conv2d如何实现深度卷积的
2020/04/20 Python
尤妮佳moony海外旗舰店:日本殿堂级纸尿裤品牌
2018/02/23 全球购物
美国在线纱线商店:Darn Good Yarn
2019/03/20 全球购物
水务局局长岗位职责
2013/11/28 职场文书
大学生创业计划书的用途
2014/01/08 职场文书
优秀干部获奖感言
2014/01/31 职场文书
惊天动地观后感
2015/06/10 职场文书
上手简单,功能强大的Python爬虫框架——feapder
2021/04/27 Python
详解Vue的sync修饰符
2021/05/15 Vue.js
详解Flutter网络请求Dio库的使用及封装
2022/04/14 Java/Android