Php 如何以请求间的方式锁定部分代码?
考虑一个PHP脚本(可能在其他脚本中调用函数)。我想确保它的某些部分一次只能由一个请求执行。例如:Php 如何以请求间的方式锁定部分代码?,php,multithreading,apache,web,locking,Php,Multithreading,Apache,Web,Locking,考虑一个PHP脚本(可能在其他脚本中调用函数)。我想确保它的某些部分一次只能由一个请求执行。例如: doSomething(); doSomethingElse(); // Lock this: Can only be executed by one request at a time yetAnotherThing(); 因此,如果请求A当前“在”doSomethingElse(),我希望在调用此函数的代码行之前,将任何进一步的请求排队 我还没有在线找到解决方案,因为我说的是请求之间的锁,而
doSomething();
doSomethingElse(); // Lock this: Can only be executed by one request at a time
yetAnotherThing();
因此,如果请求A当前“在”doSomethingElse()
,我希望在调用此函数的代码行之前,将任何进一步的请求排队
我还没有在线找到解决方案,因为我说的是请求之间的锁,而不是作为同一请求的一部分执行的单独线程的锁。我正在使用Apache服务器。您需要设置一个标志来指示应该发生什么或不应该发生什么,从而保护执行 您可以将保护状态存储在任何其他存储中,该存储跨请求持久化:数据库、会话、平面文件 您可以做的最基本的事情是编写一个标志文件。 当文件存在时,这将从处理
doSomethingElse()
中排除所有后续请求。但是,当文件消失时,下一个请求将再次执行doSomethingElse()
您可以使用
flock()
()
或者您自己的平面文件锁定方法。仅就概念而言:
添加文件内容(\uuuuu DIR\uuuu.'/doSomethingElse.processing.flag','processing')代码>
在doSomethingElse()的开头,并在函数末尾将其删除
然后将执行包装到条件检查中:
doSomething();
if( ! is_file(__DIR__.'/doSomethingElse.processing.flag')) {
doSomethingElse();
}
yetAnotherThing();
建立队列
嗯,你可以扩展给定的想法或使用准备好的库/工具来完成这项工作
要构建“队列”,您需要扩展锁的概念,并:
- 添加一个处理ID
- 添加堆栈以查找要处理的当前最低ID
- 以及查找和处理逻辑本身
- 包括已处理资源的“锁定”
队列锁定要处理的资源,并且只允许最低ID。
锁通常被称为信号量。(它实际上可能是最高的ID,这取决于您的处理逻辑——基本上是LIFO或FIFO堆栈处理。)
创建一个队列并放入作业,然后添加一个作为cronjob或守护进程运行的工作进程。工作进程从队列中取出作业,对其进行处理,并返回状态标志为“完成”的结果。然后可以定期轮询队列,查看作业是否已完成。您可以将数据库用于队列,选择一个支持锁定的数据库
while(1) {
begin new transaction;
remove item from queue;
process item;
save new state of item;
commit;
}
不确定您要去哪里,但您有很多选择来实现它:
- 有关基于文件的队列机制,请参阅本基本教程:
- 您可以依赖它,并将其与锁定思想相结合
- PHP也支持信号量:
- 然后是真正的作业队列系统,如Gearman、Beanstalk、Redis或任何消息队列,如RabbitMQ、ZeroMQ
- 参见gearman示例
您可以将doSomethingElse()函数放在另一个文件中,然后使用
flock
此功能用于防止同时访问。谢谢您的回答。但这使得任何进一步的请求都“跳过”了“锁定”部分,而我希望它们在它之前“排队”。你知道怎么做吗?或者有没有一种方法可以扩展您提出的解决方案来实现这一点?