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 相关文章推荐
The specified CGI application misbehaved by not returning a complete set of HTTP headers
Mar 31 PHP
批量获取memcache值并按key的顺序返回的实现代码
Jun 14 PHP
基于PHP文件操作的详解
Jun 05 PHP
php中cookie的使用方法
Mar 29 PHP
11个PHPer必须要了解的编程规范
Sep 22 PHP
smarty内置函数foreach用法实例
Jan 22 PHP
php上传文件常见问题总结
Feb 03 PHP
php实现网站留言板功能
Nov 04 PHP
php计算年龄精准到年月日
Nov 17 PHP
laravel5.4生成验证码的实例讲解
Aug 05 PHP
PHP判断json格式是否正确的实现代码
Sep 20 PHP
phpQuery解析HTML乱码问题(补充官网未列出的乱码解决方案)
Apr 01 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面向对象程序设计之类常量用法实例
2014/08/20 PHP
php实现将Session写入数据库
2015/07/26 PHP
PHP编写简单的App接口
2016/08/28 PHP
laravel实现上传图片的两种方式小结
2019/10/12 PHP
分享9点个人认为比较重要的javascript 编程技巧
2015/04/27 Javascript
聊一聊Vue.js过渡效果
2016/09/07 Javascript
Vue AST源码解析第一篇
2017/07/19 Javascript
Cropper.js 实现裁剪图片并上传(PC端)
2017/08/20 Javascript
vue-cli2.9.3 详细教程
2018/04/23 Javascript
如何用input标签和jquery实现多图片的上传和回显功能
2018/05/16 jQuery
在小程序中使用Echart图表的示例代码
2018/08/02 Javascript
Vue项目数据动态过滤实践及实现思路
2018/09/11 Javascript
ES10 特性的完整指南小结
2019/03/04 Javascript
vue实现微信获取用户信息的方法
2019/03/21 Javascript
监听element-ui table滚动事件的方法
2019/03/26 Javascript
AutoJs实现刷宝短视频的思路详解
2020/05/22 Javascript
AJAX XMLHttpRequest对象创建使用详解
2020/08/20 Javascript
[40:05]DOTA2上海特级锦标赛A组小组赛#1 EHOME VS MVP.Phx第一局
2016/02/25 DOTA
[00:10]DOTA2全国高校联赛速递
2018/05/30 DOTA
pycharm 使用心得(五)断点调试
2014/06/06 Python
Python实现约瑟夫环问题的方法
2016/05/03 Python
Python爬虫DNS解析缓存方法实例分析
2017/06/02 Python
python中数组和矩阵乘法及使用总结(推荐)
2019/05/18 Python
python 返回一个列表中第二大的数方法
2019/07/09 Python
如何使用Flask-Migrate拓展数据库表结构
2019/07/24 Python
Python OrderedDict的使用案例解析
2019/10/25 Python
Python3如何在服务器打印资产信息
2020/08/27 Python
Pycharm plot独立窗口显示的操作
2020/12/11 Python
python matplotlib工具栏源码探析二之添加、删除内置工具项的案例
2021/02/25 Python
国外平面设计素材网站:The Hungry JPEG
2017/03/28 全球购物
酒店端午节活动方案
2014/08/26 职场文书
2015年学校团委工作总结
2015/05/26 职场文书
上级领导检查欢迎词
2015/09/30 职场文书
表扬稿表扬信的格式及范文
2019/06/24 职场文书
导游词之包公祠
2019/11/25 职场文书
以下牛机,你有几个
2022/04/05 无线电