php 信号量 关闭,php 信号量

本文详细介绍了PHP中的信号量和共享内存如何协同工作,通过停车场案例解释了信号量的作用,并展示了如何使用sem_get和sem_acquire/s_release创建读写信号量。实例演示了如何在多线程环境下保证临界资源访问的互斥性和原子性操作。
摘要由CSDN通过智能技术生成

一些理论基础:

信号量:又称为信号灯、旗语 用来解决进程(线程同步的问题),类似于一把锁,访问前获取锁(获取不到则等待),访问后释放锁。

临界资源:每次仅允许一个进程访问的资源。

临界区:每个进程中访问临界资源的那段代码叫临界区

进程互斥:两个或以上的进程不能同时进入关于同一组共享变量的临界区域,即一个进程正在访问临界资源,另一个进程要想访问必须等待。

进程同步主要研究如何确定数个进程之间的执行顺序和避免数据竞争的问题 即,如何让多个进程能一块很好的协作运行

举例子:(来源百科)

以一个停车场的运作为例。简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆直接进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入外面的一辆进去,如果又离开两辆,则又可以放入两辆,如此往复。

在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是信号量的作用。

$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

ucos实时操作系统学习笔记——任务间通信(信号量)

ucos实时操作系统的任务间通信有好多种,本人主要学习了sem, mutex, queue, messagebox这四种.系统内核代码中,这几种任务间通信机制的实现机制相似,接下来记录一下本人对核心代 ...

Linux 信号量详解一

信号量主要用于进程间(不是线程)的互斥,通过sem_p()函数加锁使用资源,sem_v函数解锁释放资源,在加锁期间,CPU从硬件级别关闭中断,防止pv操作被打断. semget函数 int semge ...

PHP进程通信基础——信号量+共享内存通信

PHP进程通信基础--信号量+共享内存通信 由于进程之间谁先执行并不确定,这取决于内核的进程调度算法,其中比较复杂.由此有可能多进程在相同的时间内同时访问共享内存,从而造成不可预料的错误.信号量这个名 ...

C#多线程--信号量(Semaphore)

百度百科:Semaphore,是负责协调各个线程, 以保证它们能够正确.合理的使用公共资源.也是操作系统中用于控制进程同步互斥的量. Semaphore常用的方法有两个WaitOne()和Releas ...

Linux学习笔记(15)-信号量

在多线程或者多进程编程中,有一个非常需要关注的东西,那就是同步以及互斥问题. 同步是指多个进程之间的协作,而互斥是指多个进程之间,为了争夺有限的资源,而进行的竞争. 理论很高端,但经过自己几天的学习, ...

多线程之信号量(By C++)

信号量在多线程中,主要是用于线程的同步或者限制线程运行的数量. 所谓同步,当流程1运行在线程1中,流程2运行在线程2中,流程2必须在流程1结束之后才能开始执行.你会怎么做,所有就需要给出一个流程1结束 ...

信号量sem

一.什么是信号量 为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域.临界区域是指执行数据更 ...

【.NET深呼吸】线程信号量(Semaphore)

Semaphore类可以控制某个资源允许访问的线程数,Semaphore有命名式的,也有不命名的:如果不考虑跨进程工作,一般在代码中使用不命名方式即可. 信号量有点类似于等待句柄,某个线程如果调用了W ...

java多线程--信号量Semaphore的使用

Semaphore可以控制某个共享资源可被同时访问的次数,即可以维护当前访问某一共享资源的线程个数,并提供了同步机制.例如控制某一个文件允许的并发访问的数量. 例如网吧里有100台机器,那么最多只能提 ...

java多线程-信号量

Semaphore(信号量)是一个线程同步结构,用于在线程间传递信号,以避免出现信号丢失,或者像锁一样用于保护一个关键区域.自从 5.0 开始,jdk 在 java.util.concurrent 包 ...

随机推荐

使用Apache的Base64类实现Base64加解密

包名称:org.apache.commons.codec.binary 类名称:org.apache.commons.codec.binary.Base64 1.Base64加密 public sta ...

关于H5中自定义属性的设置和获取

自定义数据属性是在HTML5中新加入的一个特性.简单来说,自定义数据属性规范规定任何以data-开头属性名并且赋值.自定义数据属性是为了保存页面或者应用程序的私有自定义数据,这些自定义数据属性保存进D ...

JavaScript基础---语言基础(3)

流程控制语句 学习要点: 1.switch语句 2.for...in语句 3.break和continue语句 4.with语句 ECMA-262规定了一组流程控制语句.语句定义了ECMAScript ...

C++程序设计教程学习(0)-引子

回想一下从事C++相关开发工作已经有4年,主要从事基于MFC.Duilib等GUI框架开发进行windows应用程序开发,还涉及了一些开源的项目.但是真的谈起这门语言或多或少都会有些心虚,关于C++的 ...

Word文件交换的电脑打开字体、排版变化的原因和解决方法!

方案: 有时候.我们好不easy用Word写好文档,做好排版发给别人,别人会告诉你格式怎么是乱的啊,标题.正文.页眉页脚什么的格式都变了. 想尽各种办法都没能得到解决,那么出现这样的情况的原因究竟是什 ...

poj 3375 Network Connection

今天在叉姐的群里找点题目做,这题目还是很好的:提意思如下 [有M个可以提供计算机网络的端口和N台计算机(计算机数量少于端口数),每个端口和计算机有一个坐标(一维的)!其中端口与计算机链接的距离 |x  ...

ERROR: No pool defined. at least one pool section must be specified in config file

root@ubuntu:/opt/php7# /opt/php7/sbin/php-fpm [22-Sep-2015 14:29:00] WARNING: Nothing matches the in ...

mysql中的union用法以及子查询综合应用

union查询就是把2条或者多条sql语句的查询结果,合并成一个结果集. 如:sql1: N行,sql2: M行,sql1 union sql2 ---> N+M行 1.能否从2张表查询再uni ...

Python爬虫入门教程 5-100 27270图片爬取

27270图片----获取待爬取页面 今天继续爬取一个网站,http://www.27270.com/ent/meinvtupian/ 这个网站具备反爬,so我们下载的代码有些地方处理的也不是很到位, ...

Linux 下MQ的安装和配置亲测

开篇之前奉上几条黄金链接: MQ参考文档 http://publib.boulder.ibm.com/infocenter/wmqv7/v7r0m0/index.jsp?topic=%2Fcom.ib ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值