2011-07-21 30 views
0

當用戶上傳文件鎖文件,而不使用羊羣

exec('nohup php /main/apache2/work/upload/run.php &'); 

我使用nohup因爲它需要在後端被執行(用戶可以上傳多個文件)。

在我的原始設計run.php每次執行時都會使用scandir掃描目錄。使用flock獲取文件上的獨佔鎖LOCK_EX,並使用LOCK_NB跳過該文件,如果它有鎖並轉到下一個文件。如果文件有鎖//Do logic。問題是服務器缺少fcntl()庫,並且由於flock使用該庫來執行鎖定機制,因此flock目前不起作用。這將需要一個月或兩個月才能完成(我無法控制)。

因此,我的工作是有一個臨時文件lock.txt作爲鎖。如果文件名存在於lock.txt中,則跳過該文件並轉到下一個文件。

$dir = "/main/apache2/work/upload/files/"; 
$files = scandir($dir); 
$fileName = "lock.txt"; 

for($i=0; $i<count($files); $i++) 
{ 
    if(substr(strrchr($files[$i],'.csv'),-4) == '.csv') 
    {   
     if($file_handle = fopen("$fileName", "rb")) 
     { 
      while(!feof($file_handle)) 
      { 
       $line = fgets($file_handle); 
       $line = rtrim($line); 
       if($line == "") 
       { 
        break; 
       } 
       else 
       { 
        if($files[$i] == $line) 
        { 
         echo "Reading from lock: ".$line."</br>"; 
         $i++; //Go to next file 
        } 
       } 

      } 
      fclose($file_handle); 
     } 

     if($i >= count($files)) 
     { 
      die("$i End of file"); 
     } 

     if($file_handle = fopen("$fileName", "a+")) 
     { 
      if(is_writable($fileName)) 
      {    
       $write = fputs($file_handle, "$files[$i]"."\n"); 
       //Do logic 

       //Delete the file name - Stuck here 

       fclose($file_handle); 
      } 

     } 

    } 
    else 
    { 
     //Do nothing 
    } 
} 

如何從lock.txt刪除文件名?

更重要的是,有沒有更好的方法來鎖定一個文件在php中,而不使用flock

+1

您的運行backlground過程的方法存在缺陷 - 請參閱http://symcbean.blogspot.com/2010/02/php-and-long-running-processes.html – symcbean

+0

謝謝:) – theking963

回答

1

擁有共享鎖數據庫只是將鎖定問題移動到該文件;它並沒有解決它。

更好的解決方案是每個真實文件使用一個鎖文件。如果要鎖定對myFile.csv的訪問權限,請檢查file_exists('myFile.csv.lock')touch('myFile.csv.lock')(如果不存在)。完成後,請撥打unlink('myFile.csv.lock')

現在,file_exists()和touch()之間可能存在競爭條件,可以通過將PID存儲在文件中並檢查getmypid()是否確實是持有鎖的進程來緩解這種情況。