doufulian4076 2014-09-30 23:28
浏览 62
已采纳

为什么我的互斥类有时不会删除互斥锁文件?

I have a Wordpress plugin that I created that simply exports orders to a 3rd party system. To prevent any possible issues of the plugin running more than once at the same time, I am using the following Mutex code, however on occasion, the mutex file does not remove which stops my plugin from running until I manually remove the file.

<?php

class System_Mutex
{                         
  var $lockName = "";
  var $fileName = null;
  var $file = null; 

  public function __construct($lockName) {
    $this->lockName = preg_replace('/[^a-z0-9]/', '', $lockName);
    $this->getFileName();                         
  }

  public function __destruct() {
    $this->releaseLock();
  }

  public function isLocked() {
    return ! flock($this->file, LOCK_SH | LOCK_NB);
  }

  public function getLock() {                                                                                                                                                                                                                                                         
    return flock($this->file, LOCK_EX | LOCK_NB);    
  }

  public function releaseLock() {
    if ( ! is_resource($this->file) ) return true;          
    $success = flock($this->file, LOCK_UN);
    fclose($this->file);
    return $success;
  }

  public function getFileName() {
    $this->fileName = dirname(__FILE__) . "/../Locks/" . $this->lockName . ".lock";

    if ( ! $this->file = fopen($this->fileName, "c") ) {
      throw new Exception("Cannot create temporary lock file.");
    }                                                                                           
  }
}

The Mutex itself is used like this:

try {
  $mutex_id = "ef_stock_sync";                                                            
  $mutex = new System_Mutex($mutex_id);
  //mutex is locked- exit process
  if ( $mutex->isLocked() || ! $mutex->getLock() ) {
    //
    return; 
  }        
} catch ( Exception $e ) {
    //
    return; 
}
$this->_syncStock();
$mutex->releaseLock();

Any idea why this would be happening? I thought that the destructor of the class would ensure it is removed even if the code was to stop halfway?

  • 写回答

1条回答 默认 最新

  • dsp15140275697 2014-10-01 00:32
    关注

    Too broad to answer with certainty and the block is most likely triggered from your plugin code. However, you do have a logical error in your System_Mutex class.

    You are acquiring an exclusive lock in getLock(), but isLocked() attempts to acquire a shared lock as the check. You shouldn't do that for two reasons:

    1. A shared lock may be held by multiple processes simultaneously (hence its name).
    2. A shared lock is not prevented by an exclusive lock acquired by the same process.

    I'm not sure what you're using isLocked() for, but because of the above 2 rules, regardless of the purpose, you may get false positives. What I can tell you is this:

    • Don't mix the lock types.
    • Be careful with your lock check, because that does acquire a lock on its own.
    • In this particular case, use only LOCK_EX.

    And also this: https://bugs.php.net/bug.php?id=53769

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 springboot 3.0 实现Security 6.x版本集成
  • ¥15 PHP-8.1 镜像无法用dockerfile里的CMD命令启动 只能进入容器启动,如何解决?(操作系统-ubuntu)
  • ¥15 请帮我解决一下下面六个代码
  • ¥15 关于资源监视工具的e-care有知道的嘛
  • ¥35 MIMO天线稀疏阵列排布问题
  • ¥60 用visual studio编写程序,利用间接平差求解水准网
  • ¥15 Llama如何调用shell或者Python
  • ¥20 谁能帮我挨个解读这个php语言编的代码什么意思?
  • ¥15 win10权限管理,限制普通用户使用删除功能
  • ¥15 minnio内存占用过大,内存没被回收(Windows环境)