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 虚拟机打包apk出现错误
  • ¥30 最小化遗憾贪心算法上界
  • ¥15 用visual studi code完成html页面
  • ¥15 聚类分析或者python进行数据分析
  • ¥15 逻辑谓词和消解原理的运用
  • ¥15 三菱伺服电机按启动按钮有使能但不动作
  • ¥15 js,页面2返回页面1时定位进入的设备
  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝