请写一段 PHP 代码 ,确保多个进程同时写入同一个文件成功

方案一:

复制代码
function writeData($filepath, $data) 
{ 
    $fp = fopen($filepath,'a');  
    do{ 
        usleep(100); 
    }while (!flock($fp, LOCK_EX)); 
    
    $res = fwrite($fp, $data."\n"); 
    flock($fp, LOCK_UN); 
    fclose($fp);  
    return $res; 
} 
复制代码

本文出自 “我知” 博客,请务必保留此出处http://iknow.blog.51cto.com/6209466/1058876

方案二:

复制代码
function writeData($path, $mode,$data,$max_retries = 10)  
{  
    $fp = fopen($path, $mode);   
    $retries = 0;   
    do{  
       if ($retries > 0)   
       {  
            usleep(rand(1, 10000));  
       }  
       $retries += 1;
    }while (!flock($fp, LOCK_EX) and $retries<= $max_retries);   
    //判断是否等于最大重试次数,是则返回false
    if ($retries == $max_retries)   
    {  
       return false;  
    }  
    fwrite($fp, "$data
");  
    flock($fp, LOCK_UN);  
    fclose($fp);   
    return true;   
}
复制代码

来自http://www.xuejiehome.com/blread-1670.html

方案三:

复制代码
function write_file($filename, $content)
{
    $lock = $filename . '.lck';
    $write_length = 0;
    while(true) {
        if( file_exists($lock) ) {
            usleep(100);
        } else {
            touch($lock);
            $write_length = file_put_contents($filename, $content, FILE_APPEND);
            break;
        }
    }
    if( file_exists($lock) ) {
        unlink($lock);
    }
    return $write_length;
}
复制代码

 

flock

(PHP 4, PHP 5, PHP 7)

flock — 轻便的咨询文件锁定

bool flock ( resource $handle , int $operation [, int &$wouldblock ] )

flock() 允许执行一个简单的可以在任何平台中使用的读取/写入模型(包括大部分的 Unix 派生版和甚至是 Windows)。

在 PHP 5.3.2版本之前,锁也会被 fclose() 释放(在脚本结束后会自动调用)。

PHP 支持以咨询方式(也就是说所有访问程序必须使用同一方式锁定, 否则它不会工作)锁定全部文件的一种轻便方法。 默认情况下,这个函数会阻塞到获取锁;这可以通过下面文档中 LOCK_NB 选项来控制(在非 Windows 平台上)。

参数

handle

文件系统指针,是典型地由 fopen() 创建的 resource(资源)。

operation

operation 可以是以下值之一:

  • LOCK_SH取得共享锁定(读取的程序)。
  • LOCK_EX 取得独占锁定(写入的程序。
  • LOCK_UN 释放锁定(无论共享或独占)。

如果不希望 flock() 在锁定时堵塞,则是 LOCK_NB(Windows 上还不支持)。

wouldblock

如果锁定会堵塞的话(EWOULDBLOCK 错误码情况下),可选的第三个参数会被设置为 TRUE。(Windows 上不支持)

返回值

成功时返回 TRUE, 或者在失败时返回 FALSE

Example #1 flock() 例子

复制代码
<?php

$fp = fopen("/tmp/lock.txt", "r+");

if (flock($fp, LOCK_EX)) {  // 进行排它型锁定
    ftruncate($fp, 0);      // truncate file
    fwrite($fp, "Write something here\n");
    fflush($fp);            // flush output before releasing the lock
    flock($fp, LOCK_UN);    // 释放锁定
} else {
    echo "Couldn't get the lock!";
}

fclose($fp);

?>
复制代码

Example #2 flock() 使用 LOCK_NB 选项

复制代码
<?php
$fp = fopen('/tmp/lock.txt', 'r+');

/* Activate the LOCK_NB option on an LOCK_EX operation */
if(!flock($fp, LOCK_EX | LOCK_NB)) {
    echo 'Unable to obtain lock';
    exit(-1);
}

/* ... */

fclose($fp);
?>
复制代码

Note:

由于 flock() 需要一个文件指针, 因此可能不得不用一个特殊的锁定文件来保护打算通过写模式打开的文件的访问(在 fopen() 函数中加入 "w" 或 "w+")。

Warning:

在部分操作系统中 flock() 以进程级实现。当用一个多线程服务器 API(比如 ISAPI)时,可能不可以依靠 flock() 来保护文件,因为运行于同一服务器实例中其它并行线程的 PHP 脚本可以对该文件进行处理。

flock() 不支持旧的文件系统,如 FAT 以及它的派生系统。因此,此环境下总是返回 FALSE(尤其是对 Windows 98 用户来说)。

http://php.net/manual/zh/function.flock.php

转自:https://www.cnblogs.com/gengyi/p/6399206.html

posted @ 2019-10-19 21:46  王的微笑  阅读(1300)  评论(0编辑  收藏  举报