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中进行身份认证
Oct 09 PHP
用PHP查询域名状态whois的类
Nov 25 PHP
php 连接mssql数据库 初学php笔记
Mar 01 PHP
PHP函数http_build_query使用详解
Aug 20 PHP
写一段简单的PHP建立文件夹代码
Jan 06 PHP
PHP连接MSSQL方法汇总
Feb 05 PHP
ucenter中词语过滤原理分析
Jul 13 PHP
PHP实现绘制二叉树图形显示功能详解【包括二叉搜索树、平衡树及红黑树】
Nov 16 PHP
购物车实现的几种方式优缺点对比
May 02 PHP
PHP实现一个轻量级容器的方法
Jan 28 PHP
浅谈laravel中的关联查询with的问题
Oct 10 PHP
laravel框架路由分组,中间件,命名空间,子域名,路由前缀实例分析
Feb 18 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循环函数使用介绍之PHP基础入门教程
2013/09/21 PHP
PHP十六进制颜色随机生成器功能示例
2017/07/24 PHP
bgsound 背景音乐 的一些常用方法及特殊用法小结
2010/05/11 Javascript
JS写的贪吃蛇游戏(个人练习)
2013/07/08 Javascript
JS拖拽插件实现步骤
2015/08/03 Javascript
Javascript连接Access数据库完整实例
2015/08/03 Javascript
JS当前页面登录注册框,固定DIV,底层阴影的实例代码
2016/09/29 Javascript
AngularJS递归指令实现Tree View效果示例
2016/11/07 Javascript
layui前段框架日期控件使用方法详解
2017/05/19 Javascript
json2.js 入门教程之使用方法与实例分析
2017/09/14 Javascript
JS代码实现电脑配置检测功能
2018/03/21 Javascript
基于Nodejs的Tcp封包和解包的理解
2018/09/19 NodeJs
react+redux仿微信聊天界面
2019/06/21 Javascript
javascript实现画板功能
2020/04/12 Javascript
微信小程序文章列表功能完整实例
2020/06/03 Javascript
vue+iview分页组件的封装
2020/11/17 Vue.js
详谈Python2.6和Python3.0中对除法操作的异同
2017/04/28 Python
python中sys.argv函数精简概括
2018/07/08 Python
python 实现UTC时间加减的方法
2018/12/31 Python
Python3爬虫之自动查询天气并实现语音播报
2019/02/21 Python
python中yield的用法详解——最简单,最清晰的解释
2019/04/04 Python
Python3如何在服务器打印资产信息
2020/08/27 Python
CSS3 3D位移translate效果实例介绍
2016/05/03 HTML / CSS
世界闻名的衬衫制造商:Savile Row Company
2018/07/30 全球购物
英国和爱尔兰最大的地毯零售商:Kukoon
2018/12/17 全球购物
医学护理系毕业生求职信
2013/10/01 职场文书
小学新学期教师寄语
2014/01/18 职场文书
财务信息服务专业自荐书范文
2014/02/08 职场文书
小学生综合素质评语
2014/04/23 职场文书
人民调解员培训方案
2014/06/05 职场文书
应用心理学专业求职信
2014/08/04 职场文书
酒店七夕情人节活动策划方案
2014/08/24 职场文书
农林经济管理专业自荐信
2014/09/01 职场文书
员工考勤管理制度
2015/08/06 职场文书
MySQL锁机制
2021/04/05 MySQL
nginx刷新页面出现404解决方案(亲测有效)
2022/03/18 Servers