alternative php cache semaphore,如何正确使用PHP5信号灯?

我有这个功能,试图从缓存中读取一些值.但是,如果值不存在,则应调用备用源API并将新值保存到缓存中.但是,服务器非常过载,几乎每次不存在值时,就会创建一个请求(许多API调用),并且每个请求都会将新值存储到缓存中.但是,我想要的是能够多次调用API,但是只有一个进程/请求能够将其存储在缓存中:

function fetch_cache($key, $alternativeSource) {

$redis = new Redis();

$redis->pconnect(ENV_REDIS_HOST);

$value = $redis->get($key);

if( $value === NULL ) {

$value = file_get_contents($alternativeSource);

// here goes part that I need help with

$semaphore = sem_get(6000, 1); // does this need to be called each time this function is called?

if( $semaphore === FALSE ) {

// This means I have failed to create semaphore?

}

if( sem_aquire($semaphore, true) ) {

// we have aquired semaphore so here

$redis->set($key, $value);

sem_release($semaphore); // releasing lock

}

// This must be call because I have called sem_get()?

sem_remove($semaphore);

}

return $value;

}

PHP5是否正确使用了信号量?

解决方法:

简短答案

>您无需在fetch_cache函数中创建和删除信号量.将sem_get()放入初始化方法(例如__construct)中.

>您应该使用sem_remove()删除信号量,但是要使用清理方法(例如__destruct).或者,您可能希望将它们保留更长的时间-取决于应用程序的逻辑.

>使用sem_acquire()获取锁,然后使用sem_release()释放锁.

描述

sem_get()

创建一组three信号量.

底层的C函数semget不是原子的.当两个进程尝试调用semget时,可能会出现race condition.因此,应在某些初始化过程中调用semget. PHP扩展通过三个信号量克服了这个问题:

信号量0亦称SYSVSEM_SEM

初始化为sem_get的$max_acquire,并在进程获取时递减.

第一个调用sem_get的进程将获取SYSVSEM_USAGEsemaphore的值(请参见下文).对于第一个过程,它等于1,因为扩展名sets it to 1在semget之后具有原子semop函数.并且,如果这确实是第一个过程,则扩展会将SYSVSEM_SEM信号量值分配给$max_acquire.

信号灯1又称SYSVSEM_USAGE

使用信号量的进程数.

信号量2又称SYSVSEM_SETVAL

充当内部SETVAL和GETVAL操作的锁(请参见man 2 semctl).例如,将其设置为1,而扩展名将SYSVSEM_SEM设置为$max_acquire,然后将其重置为零.

最后,sem_get将一个结构(包含信号量集ID,键和其他信息)包装到PHP资源中并返回它.

因此,当您仅准备使用信号量时,应该在一些初始化过程中调用它.

sem_acquire()

这是$max_acquire goes into play的位置.

SYSVSEM_SEM的值(我们称其为semval)最初等于$max_acquire. semop()阻塞,直到semval大于或等于1.然后从semval中减去1.

如果$max_acquire = 1,则在第一次调用之后semval变为零,并且对sem_acquire()的下一次调用将填充块,直到通过sem_release()调用恢复semval.

需要从可用集中($max_acquire)获取下一个“锁”时调用它.

sem_release()

与sem_acquire()几乎一样,只是它增加了SYSVSEM_SEM的值.

当您不再需要以前通过sem_acquire()获取的“锁”时调用它.

sem_remove()

立即删除信号量集,唤醒该集中的semop中阻塞的所有进程(来自IPC_RMID部分,SEMCTL(2)手册页).

因此,这实际上与使用ipcrm命令删除信号量相同.

标签:semaphore,php

来源: https://codeday.me/bug/20191118/2025415.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值