我需要在PHP中有一个互斥方法,以便通过变量值保持排他性。这就是说,具有相同值的线程应该每次输入一个方法,而具有不同值的线程可以任意访问该方法。如何在PHP中创建每个变量值的互斥方法
例如,给定该方法:
/**
* @param integer $value
*/
function mutexMethod($value)
{
// Lock for value $value
echo 'processing';
sleep(2);
echo 'this is so heavy';
// Unlock for value $value
}
例如(我需要这通过Apache运行):
time |
0 | php > mutexMethod(1); | php > mutexMethod(2); | php > mutexMethod(1);
1 | processing | processing |
2 | | |
3 | this is so heavy | this is so heavy | processing
4 | | |
5 | | | this is so heavy
作为第一溶液中,我使用semaphores尝试,但因为$value
可能会得到任何值,所以我已经很快用完了信号量空间(我试过在使用它们后删除信号量,但是这会中断其他线程,因为我不知道是否有任何线程在等待它们,我不能删除他们的任意随手。
作为第二种解决方案,我尝试创建一个值为$value
的文件作为名称,并使用flock
来锁定其他任何线程。尽管这在CLI中有效,但我无法通过apache设置它。它当然锁定了文件,但它从未释放该锁,所以其他任何请求都会卡住,直到第一个请求超时(30秒后)。
最后我虽然关于使用MySQL锁,但我想尽量避免它们,因为我们不希望将MySQL实例用于这种事情。理想情况下,我们需要一个纯PHP解决方案。
你有什么想法解决这个问题吗?我想避免使用单信号量解决方案(比如有一个单一的信号量来控制对跟踪锁的文件的访问),因为这会造成巨大的瓶颈(特别是对于具有不同值的线程)。
非常感谢。
你能详细解释你正在解决的更广泛的问题吗?从我所看到的情况来看,可能的解决方案可能是将值存储在一个集合中,并创建存取函数,以便线程必须获取互斥锁才能修改集合成员资格。这样,你将有一个线程同步的方式来“签出”和“签入”$ value's。 – aednichols
我试图解决网络上的竞争条件,以便用户触发算法来为具有ID的对象执行一些计算(相对昂贵和耗时)。所以我们的想法是,根据这个ID,“排队”或简单地阻止请求并逐一处理它们。如果我允许同一个ID同时执行请求,我可能会放弃以前的计算。问题是,对不同ID的请求可以同时执行而没有任何缺点。 – carlosV2
每个特定ID的计算结果是否相同?听起来像你应该考虑[记忆](https://en.wikipedia.org/wiki/Memoization) – aednichols