0

当用户上传文件时(用户可以上传多个文件)

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

我正在使用nohup它,因为它需要在后端执行。

在我的原始设计中,每次执行时都会run.php扫描目录。scandir获取文件的排他锁LOCK_EX,如果文件有锁,则flock使用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

4

1 回答 1

1

拥有一个共享锁数据库只是将锁定问题转移到该文件;它不能解决它。

一个更好的解决方案是每个真实文件使用一个锁定文件。如果您想锁定访问权限,myFile.csv请检查file_exists('myFile.csv.lock')touch('myFile.csv.lock')是否不存在。unlink('myFile.csv.lock')完成后。

现在,file_exists() 和 touch() 之间可能存在竞争条件,可以通过将 PID 存储在文件中并检查是否getmypid()确实是持有锁的进程来缓解这种情况。

于 2011-07-21T15:02:07.123 回答