以线程安全的方式创建文件

zer*_*kms 7 php locking file-locking thread-safety

我有一个文件名数组,每个进程只需要创建和写入一个文件.

这就是我的意思:

foreach ($filenames as $VMidFile) {
    if (file_exists($VMidFile)) { // A
        continue;
    }

    $fp = fopen($VMidFile, 'c'); // B

    if (!flock($fp, LOCK_EX | LOCK_NB)) { // C
        continue;
    }

    if (!filesize($VMidFile)) { // D
        // write to the file;

        flock($fp, LOCK_UN);
        fclose($fp);
        break;
    }

    flock($fp, LOCK_UN);
    fclose($fp); // E
}
Run Code Online (Sandbox Code Playgroud)

但我不喜欢我依靠的filesize.

有什么建议以另一种(更好的)方式做到这一点?

UPD:添加标签以便轻松讨论

UPD 2:我正在使用,filesize因为我没有看到任何其他可靠的方法来检查当前线程是否创建了文件(因此它还是空的)

UPD 3:解决方案应该是无条件竞赛.

Jim*_*Jim 4

一个可能的、稍微丑陋的解决方案是锁定一个锁定文件,然后测试该文件是否存在:

$lock = fopen("/tmp/".$filename."LOCK", "w"); // A

if (!flock($lock, LOCK_EX)) { // B
    continue;
}
if(!file_exists($filename)){ // C
    //File doesn't exist so we know that this thread will create it
    //Do stuff to $filename
    flock($lock, LOCK_UN); // D
    fclose($lock);
}else{
    //File exists. This thread didn't create it (at least in this iteration).
    flock($lock, LOCK_UN);
    fclose($lock);
}
Run Code Online (Sandbox Code Playgroud)

这应该允许对该文件进行独占访问,并且还允许决定是否调用fopen($VMidFile, 'c');将创建该文件。