php 任务 信号量,PHP信号量实现简单的具备表锁高速共享内存Table

本文介绍了如何在Linux环境中使用信号量实现多进程表锁,通过一个名为`Table`的类展示了如何进行共享内存的读写操作,并提供了基于信号量的并发控制。示例代码中,`Table`类包含了写入、读取、更新和删除共享内存数据的方法,并在`Process`类中演示了多进程间的并发操作。此实现确保了进程间的数据同步和互斥访问。
摘要由CSDN通过智能技术生成

最近研究liunx 服务器多进程并发发现进程并发之间有很多问题,最主要的就是内容协同,遂做了一个简单的基于liunx信号量实现的表锁的table类拿出来分享一下

namespace Table;

/* 基于表锁的多进程共享内存 */

class Table

{

/* 共享内存句柄 */

protected $shm_resource;

/* 信号量句柄 */

protected $signal;

/**

* Table constructor.

*

* @param int table size

*/

public function __construct($size=1024)

{

/* 生成共享内存句柄 */

$shm_mem=shm_attach(ftok(__FILE__,'a'),$size,0666);

/* 共享内存句柄挂载 */

$this->shm_resource=$shm_mem;

/* 挂载信号量 */

$this->signal=sem_get(ftok(__FILE__,'b'));

}

/**

* 共享内存写入消息

*

* @param int $key

* @param string $value

* @param bool serialize

* @return bool isWriteSuccess

*/

public function writeMem(int $key,string $value,bool $serialize=TRUE)

{

if(sem_acquire($this->signal))

{

/* 写入共享内存数据 */

$writeRes=shm_put_var($this->shm_resource,$key,$serialize?serialize($value):$value);

/* 释放信号量 */

sem_release($this->signal);

return $writeRes;

}

}

/**

* 获取共享内存消息

*

*

* @param int $key

* @param bool $unserialize

* @return string content

*/

public function readMem(int $key,bool $unserialize=TRUE)

{

if(sem_acquire($this->signal))

{

/* 读取共享内存资源 */

$content=shm_get_var($this->shm_resource,$key);

$content=$unserialize?unserialize($content):$content;

/* 释放信号量 */

sem_release($this->signal);

return $content;

}

}

/**

* 原子修改行内容

*

*

* @param int $key

* @param \Closure $func

* @param bool $serialize

* @return bool 写入状态

*/

public function updateMem(int $key,\Closure $func,bool $serialize=TRUE)

{

/* 闭包修改 */

$res=call_user_func($func,$this->readMem($key));

/* 写入共享内存 */

return (bool)$this->writeMem($key,$res);

}

/**

* 删除表中k值

*

*

* @param int $key

* @return bool

*/

public function delMem(int $key)

{

/* 检查是否存在 */

if(!shm_has_var($this->shm_resource,$key))return false;

/* 清除内容 */

if(sem_acquire($this->signal))

{

/* 执行删除 */

$status=(bool)shm_remove_var($this->shm_resource,$key);

/* 释放信号量 */

sem_release($this->signal);

return $status;

}

/* 无任何返回false */

return false;

}

/**

* 析构函数

*/

public function __destruct()

{

// TODO: Implement __destruct() method.

/* 清空信号量句柄 */

sem_remove($this->signal);

/* 清空共享内存 */

shm_detach($this->shm_resource);

}

}

以上的table类实现了基于sem信号自动排队操作表的功能下面给个多进程操作的案例

namespace process

class Process

{

public function getInfo()

{

/* 实例化类 */

$table=new \Table\Table();

$pid=pcntl_fork();

if($pid==0)

{

/* 子进程逻辑 */

/* 共享表写入 */

while(true)

{

echo '子进程等待获取表锁'.PHP_EOL;

$table->writeMem(1,time());

echo '子进程已释放表锁'.PHP_EOL;

sleep(2);

}

}

elseif($pid>0)

{

/* 父进程逻辑 */

/* 父进程读取 */

while (true)

{

echo '父进程获取表锁'.PHP_EOL;

echo $table->readMem(1).PHP_EOL;

echo '父进程释放表锁'.PHP_EOL;

sleep(2);

}

}

}

}

以上就是最简单的基于信号量的表锁table , 后续考虑实现基于行锁的表。

ps: 最后在备注一下,该类实现的读写均有锁,默认所有表的操作均会触发信号量调度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值