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与javascript的两种交互方式
Oct 09 PHP
PHP动态变静态原理
Nov 25 PHP
在PHP中养成7个面向对象的好习惯
Jan 28 PHP
php数字转汉字代码(算法)
Oct 08 PHP
php之Memcache学习笔记
Jun 17 PHP
通过php添加xml文档内容的方法
Jan 23 PHP
thinkphp3.2中Lite文件替换框架入口文件或应用入口文件的方法
May 21 PHP
[原创]PHP字符串中插入子字符串方法总结
May 06 PHP
php mongodb操作类 带几个简单的例子
Aug 25 PHP
php+ajax无刷新上传图片的实现方法
Dec 06 PHP
Laravel中获取路由参数Route Parameters的五种方法示例
Sep 29 PHP
如何直接访问php实例对象中的private属性详解
Oct 12 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
Discuz 5.0 中读取纯真IP数据库函数分析
2007/03/16 PHP
php读取csc文件并输出
2015/05/21 PHP
纯php生成随机密码
2015/10/30 PHP
谈谈php对接芝麻信用踩的坑
2016/12/01 PHP
PHP实现深度优先搜索算法(DFS,Depth First Search)详解
2017/09/16 PHP
php新建文件的方法实例
2019/09/26 PHP
javascript 一个函数对同一元素的多个事件响应
2009/07/25 Javascript
JavaScript中的isXX系列是否继续使用的分析
2011/04/16 Javascript
JavaScript字符串String和Array操作的有趣方法
2012/12/18 Javascript
window.navigate 与 window.location.href 的使用区别介绍
2013/09/21 Javascript
jquery动态添加option示例
2013/12/30 Javascript
利用js读取动态网站从服务器端返回的数据
2014/02/10 Javascript
php,js,css字符串截取的办法集锦
2014/09/26 Javascript
使用cluster 将自己的Node服务器扩展为多线程服务器
2014/11/10 Javascript
jQuery实现获取元素索引值index的方法
2016/09/18 Javascript
AngularJS控制器之间的通信方式详解
2016/11/03 Javascript
Node.js之网络通讯模块实现浅析
2017/04/01 Javascript
javaScript字符串工具类StringUtils详解
2017/12/08 Javascript
使用vue.js在页面内组件监听scroll事件的方法
2018/09/11 Javascript
4个顶级JavaScript高级文本编辑器
2018/10/10 Javascript
Element input树型下拉框的实现代码
2018/12/21 Javascript
小程序云函数调用API接口的方法
2019/05/17 Javascript
微信小程序实现购物车代码实例详解
2019/08/29 Javascript
jQuery实现提交表单时不提交隐藏div中input的方法
2019/10/08 jQuery
如何基于js判断浏览器版本
2020/02/20 Javascript
Python中optparse模块使用浅析
2015/01/01 Python
详解 Python中LEGB和闭包及装饰器
2017/08/03 Python
python中Lambda表达式详解
2019/11/20 Python
pytorch中 gpu与gpu、gpu与cpu 在load时相互转化操作
2020/05/25 Python
什么是Python变量作用域
2020/06/03 Python
Pycharm的Available Packages为空的解决方法
2020/09/18 Python
HTML5中新标签和常用标签详解
2014/03/07 HTML / CSS
HTML5拖拉上传文件的简单实例
2017/01/11 HTML / CSS
好莱坞百老汇御用王牌美妆:Koh Gen Do 江原道
2018/04/03 全球购物
优秀研究生主要事迹
2014/06/03 职场文书
springboot+rabbitmq实现智能家居实例详解
2022/07/23 Java/Android