Maison >développement back-end >Problème PHP >Comment PHP résout-il le problème de plusieurs processus écrivant un fichier en même temps ?

Comment PHP résout-il le problème de plusieurs processus écrivant un fichier en même temps ?

coldplay.xixi
coldplay.xixioriginal
2020-06-30 15:58:393542parcourir

Méthode php pour résoudre le problème de plusieurs processus écrivant un fichier en même temps : copiez d'abord le fichier qui doit être mis à jour et changez le nom du fichier puis vérifiez si l'heure de la dernière mise à jour est cohérente avec la précédente ; gain de temps ; enfin, modifiez le fichier temporaire. Renommez-le en fichier d'origine.

Comment PHP résout-il le problème de plusieurs processus écrivant un fichier en même temps ?


méthode php pour résoudre le problème de plusieurs processus écrivant un fichier à la fois en même temps :

Tout d'abord, PHP prend en charge les processus mais pas le multi-threading (clarifiez-le d'abord). S'il s'agit d'une opération sur un fichier, il vous suffit de verrouiller le fichier pour résoudre le problème. d'autres opérations sont nécessaires. PHP flock l'a fait pour vous.
Utilisez flock pour verrouiller le fichier avant l'écriture et le déverrouiller après l'écriture. Cela permet à plusieurs threads de lire et d'écrire un fichier en même temps pour éviter les conflits. Il s'agit probablement du processus suivant

/*
*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);
)

Recommandations d'apprentissage associées : Programmation PHP de l'entrée à la maîtrise

Solution : Ne pas utiliser flock fonction, utilisez des fichiers temporaires pour résoudre les conflits de lecture et d'écriture.

Le principe général est le suivant :

(1) Mettez une copie du fichier qui doit être mis à jour dans notre répertoire de fichiers temporaires, enregistrez l'heure de dernière modification du fichier à une variable, et définissez ceci. Le fichier temporaire prend un nom de fichier aléatoire, peu susceptible d'être répété.

(2) Après avoir mis à jour ce fichier temporaire, vérifiez si l'heure de la dernière mise à jour du fichier d'origine est cohérente avec l'heure précédemment enregistrée.

(3) Si l'heure de la dernière modification est la même, renommez le fichier temporaire modifié en fichier d'origine Afin de garantir que l'état du fichier est mis à jour de manière synchrone, l'état du fichier doit être effacé.

(4) Cependant, si l'heure de la dernière modification est cohérente avec celle enregistrée précédemment, cela signifie que le fichier d'origine a été modifié pendant cette période, et le fichier temporaire doit être supprimé. puis retournez false, indiquant que le fichier est actuellement exploité par d'autres processus.

Le code d'implémentation est le suivant :

Le code est le suivant :

$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');

Pour les fonctions utilisées dans le code ci-dessus, il faut expliquer :

(1)rename();Renommer un fichier ou un répertoire Cette fonction ressemble en fait plus à mv sous Linux. Il est pratique de mettre à jour le chemin ou le nom d'un fichier ou d'un répertoire. Mais lorsque je teste le code ci-dessus dans la fenêtre, si le nouveau nom de fichier existe déjà, un avis sera émis indiquant que le fichier actuel existe déjà. Mais ça marche bien sous Linux.

(2)clearstatcache();Effacer l'état du fichier. PHP mettra en cache toutes les informations sur les attributs du fichier pour offrir de meilleures performances, mais parfois, lorsque plusieurs processus suppriment ou mettent à jour des fichiers, PHP n'a pas le temps de mettre à jour le fichier. les attributs dans le cache peuvent facilement conduire à l'accès à des données qui ne correspondent pas à l'heure de la dernière mise à jour. Vous devez donc ici utiliser cette fonction pour vider le cache enregistré.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn