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生成静态页
Nov 25 PHP
Mysql和网页显示乱码解决方法集锦
Mar 27 PHP
网站用php实现paypal整合方法
Nov 28 PHP
PHP ? EasyUI DataGrid 资料存的方式介绍
Nov 07 PHP
PHP根据传入参数合并多个JS和CSS文件的简单实现
Jun 13 PHP
php 删除cookie方法详解
Dec 01 PHP
php实现mysql备份恢复分卷处理的方法
Dec 26 PHP
PHP通过微信跳转的Code参数获取用户的openid(关键代码)
Jul 06 PHP
PHP数组生成XML格式数据的封装类实例
Nov 10 PHP
thinkphp关于简单的权限判定方法
Apr 03 PHP
PHP实现在数据库百万条数据中随机获取20条记录的方法
Apr 19 PHP
PHP实现单例模式建立数据库连接的方法分析
Feb 11 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实现根据银行卡号判断银行
2015/04/29 PHP
javascript之对系统的toFixed()方法的修正
2007/05/08 Javascript
Extjs grid panel自带滚动条失效的解决方法
2014/09/11 Javascript
javascript实现类似超链接的效果
2014/12/26 Javascript
Eclipse配置Javascript开发环境图文教程
2015/01/29 Javascript
js表单中选择框值的获取及表单的序列化
2015/12/17 Javascript
JavaScript实现输入框(密码框)出现提示语
2016/01/12 Javascript
javascript实现label标签跳出循环操作
2016/03/06 Javascript
浅谈JavaScript中变量和函数声明的提升
2016/08/09 Javascript
js实现String.Fomat的实例代码
2016/09/02 Javascript
jQuery 特性操作详解及实例代码
2016/09/29 Javascript
微信小程序 Toast自定义实例详解
2017/01/20 Javascript
Node.js readline 逐行读取、写入文件内容的示例
2018/03/01 Javascript
JS求Number类型数组中最大元素方法
2018/04/08 Javascript
vue+axios新手实践实现登陆的示例代码
2018/06/06 Javascript
vue实现可视化可拖放的自定义表单的示例代码
2019/03/20 Javascript
Vue 3.x+axios跨域方案的踩坑指南
2019/07/04 Javascript
[05:13]TI4 中国战队 机场出征!!
2014/07/07 DOTA
Python网络爬虫出现乱码问题的解决方法
2017/01/05 Python
基于python 爬虫爬到含空格的url的处理方法
2018/05/11 Python
Python实现获取本地及远程图片大小的方法示例
2018/07/21 Python
python 获取等间隔的数组实例
2019/07/04 Python
Django如何使用第三方服务发送电子邮件
2019/08/14 Python
python中自带的三个装饰器的实现
2019/11/08 Python
Python configparser模块常用方法解析
2020/05/22 Python
如何利用Python 进行边缘检测
2020/10/14 Python
Python读写锁实现实现代码解析
2020/11/28 Python
详解HTML5中的manifest缓存使用
2015/09/09 HTML / CSS
美国受欢迎的女性牛仔裤品牌:DL1961
2016/11/12 全球购物
大学生开西餐厅创业计划书
2014/02/01 职场文书
素质教育标语
2014/06/27 职场文书
基层干部个人对照检查及整改措施
2014/10/28 职场文书
2014年法院工作总结
2014/11/24 职场文书
道歉的话怎么说
2015/05/12 职场文书
2016高一新生军训心得体会
2016/01/11 职场文书
详解Spring Bean的配置方式与实例化
2022/06/10 Java/Android