>백엔드 개발 >PHP 문제 >PHP는 동시에 파일을 작성하는 여러 프로세스의 문제를 어떻게 해결합니까?

PHP는 동시에 파일을 작성하는 여러 프로세스의 문제를 어떻게 해결합니까?

coldplay.xixi
coldplay.xixi원래의
2020-06-30 15:58:393544검색

동시에 파일을 작성하는 여러 프로세스의 문제를 해결하는 php 방법: 먼저 업데이트해야 하는 파일을 복사하고 파일 이름을 변경한 다음 마지막 업데이트 시간이 이전에 저장된 시간과 일치하는지 확인합니다. , 수정된 임시 파일의 이름을 원본 문서로 바꿉니다.

PHP는 동시에 파일을 작성하는 여러 프로세스의 문제를 어떻게 해결합니까?


여러 프로세스가 동시에 파일을 쓰는 문제를 해결하는 PHP 방법:

우선, PHP는 프로세스를 지원하지만 멀티 스레딩은 지원하지 않습니다(먼저 명확히 하세요). 파일 작업을 위한 것이라면 실제로 문제를 해결하기 위해 파일을 잠그기만 하면 됩니다. PHP 무리가 이미 해당 작업을 수행할 필요는 없습니다.
무리를 사용하여 쓰기 전에 파일을 잠그고 쓰기 후에 잠금을 해제하세요. 이렇게 하면 여러 스레드가 동시에 파일을 읽고 쓸 수 있어 충돌을 피할 수 있습니다. 아마도 다음과 같은 과정일 것입니다.

/*
*flock(file,lock,block)
*file 必需,规定要锁定或释放的已打开的文件
*lock 必需。规定要使用哪种锁定类型。
*block 可选。若设置为 1 或 true,则当进行锁定时阻挡其他进程。
*lock
*LOCK_SH 要取得共享锁定(读取的程序)
*LOCK_EX 要取得独占锁定(写入的程序)
*LOCK_UN 要释放锁定(无论共享或独占)
*LOCK_NB 如果不希望 flock() 在锁定时堵塞
/*
if (flock($file,LOCK_EX))
{
fwrite($file,'write more words');
flock($file,LOCK_UN);
}
else
{
//处理错误逻辑
}
fclose($file);
)

관련 학습 권장 사항: PHP 프로그래밍 입문부터 숙련까지

해결 방법: 무리 기능을 사용하지 말고 임시 파일을 사용하여 읽기 및 쓰기 충돌 문제를 해결하세요.

일반적인 원칙은 다음과 같습니다.

(1) 임시 파일 디렉터리로 업데이트해야 하는 파일의 복사본을 고려하고, 파일의 마지막 수정 시간을 변수에 저장하고, 해당 파일에 대한 임의의 복사본을 선택합니다. 파일 이름을 반복하기 쉽지 않은 임시 파일입니다.

(2) 임시 파일을 업데이트한 후 원본 파일의 마지막 업데이트 시간이 이전에 저장된 시간과 일치하는지 확인하세요.

(3) 마지막 수정 시간이 동일한 경우 수정된 임시 파일의 이름을 원본 파일로 변경하여 파일 상태가 동기적으로 업데이트되도록 하려면 파일 상태를 지워야 합니다.

(4) 그러나 마지막 수정 시간이 이전에 저장된 시간과 일치하면 이 기간 동안 원본 파일이 수정되었음을 의미하며 이때 임시 파일을 삭제한 후 false를 반환해야 함을 나타냅니다. 현재 다른 프로세스가 작동 중입니다.

구현 코드는 다음과 같습니다.

코드는 다음과 같습니다.

$dir_fileopen='tmp';
function randomid(){
    return time().substr(md5(microtime()),0,rand(5,12));
}
function cfopen($filename,$mode){
    global $dir_fileopen;
    clearstatcache();
    do{
  $id=md5(randomid(rand(),TRUE));
        $tempfilename=$dir_fileopen.'/'.$id.md5($filename);
    } while(file_exists($tempfilename));
    if(file_exists($filename)){
        $newfile=false;
        copy($filename,$tempfilename);
    }else{
        $newfile=true;
    }
    $fp=fopen($tempfilename,$mode);
    return $fp?array($fp,$filename,$id,@filemtime($filename)):false;
}
function cfwrite($fp,$string){
 return fwrite($fp[0],$string);
}
function cfclose($fp,$debug='off'){
    global $dir_fileopen;
    $success=fclose($fp[0]);
    clearstatcache();
    $tempfilename=$dir_fileopen.'/'.$fp[2].md5($fp[1]);
    if((@filemtime($fp[1])==$fp[3])||($fp[4]==true&&!file_exists($fp[1]))||$fp[5]==true){
        rename($tempfilename,$fp[1]);
    }else{
        unlink($tempfilename);
  //说明有其它进程 在操作目标文件,当前进程被拒绝
        $success=false;
    }
    return $success;
}
$fp=cfopen('lock.txt','a+');
cfwrite($fp,"welcome to beijing.\n");
fclose($fp,'on');

위 코드에서 사용된 함수에 대해서는 설명이 필요합니다.

(1) rename();파일이나 디렉토리의 이름을 바꾸세요. 이 기능은 실제로 Linux의 mv와 비슷합니다. 파일이나 디렉터리의 경로나 이름을 업데이트하는 것이 편리합니다. 하지만 위 코드를 윈도우에서 테스트할 때 새 파일 이름이 이미 존재하면 현재 파일이 이미 존재한다는 알림이 표시됩니다. 하지만 리눅스에서는 잘 작동합니다. rename();重命名一个文件或一个目录,该函数其实更像linux里的mv。更新文件或者目录的路径或名字很方便。但当我在window测试上面代码时,如果新文件名已经存在,会给出一个notice,说当前文件已经存在。但在linux下工作的很好。

(2)clearstatcache();

(2) clearstatcache();파일 지우기 status.php는 더 높은 성능을 제공하기 위해 모든 파일 속성 정보를 캐시하지만 때로는 여러 프로세스가 파일을 삭제하거나 업데이트하는 경우 PHP에 그럴 시간이 없습니다. 캐시의 파일 속성을 업데이트하면 마지막으로 액세스한 업데이트 시간이 실제 데이터가 아니라는 사실이 쉽게 나타날 수 있습니다. 따라서 저장된 캐시를 지우려면 이 기능을 사용해야 합니다. 🎜

위 내용은 PHP는 동시에 파일을 작성하는 여러 프로세스의 문제를 어떻게 해결합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.