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

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

这就是我的意思:

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
}

但我不喜欢我依赖文件大小.

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

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

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

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

一个可能的,稍微丑陋的解决方案是锁定一个文件,然后测试该文件是否存在:
$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);
}

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

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...