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(),我希望在调用此函数的代码行之前,将任何进一步的请求排队 我还没有在线找到解决方案,因为我说的是请求之间的锁,而

考虑一个PHP脚本(可能在其他脚本中调用函数)。我想确保它的某些部分一次只能由一个请求执行。例如:

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


此功能用于防止同时访问。

谢谢您的回答。但这使得任何进一步的请求都“跳过”了“锁定”部分,而我希望它们在它之前“排队”。你知道怎么做吗?或者有没有一种方法可以扩展您提出的解决方案来实现这一点?