Forum Programmation.php PHP: Lock sur le system de fichier ?

Posté par  (site web personnel) .
Étiquettes : aucune
0
20
août
2005
je voudrais en PHP effectuer des lock sur le system de fichier, pour etre sur que le dit script server puisse modifier le contenu d un dossier (enfin, un dossier qui ne contiendrait que 4 fichiers texte), sans etre mis en concurrence par d autres instances.

Je me tape de savoir si une requette echoue. L essentiel est que si due requettes web arrivent exactement en meme temps, un seul script PHP pourra modifier les documetns locaux a la fois. L autre acces devrait idealement detecter qu il n est pas seul sur le coup, et abandonner immediatement (le message de sortie impotre peu).

Mon but est de modifier des listnigs de petite taille (entre 1ko et 10ko) avec un parseur tres leger, donc l execution sera rapide, le probleme etant que le parseur modifie FORCEMENT le dit fichier, et quand il le modifie, il ne faut qu aucun autre parseure ne puisse rien lire (sur aucun des 4 fichiers d archive).

Je sais que normalement on peu faire de beaux locks en SQL, mais justement, la ou j essaye d innover, c est de faire des locks SANS SQL.

Donc je pensais a des fichiers lock dans un dossier particulier ... mais je n ai aucune experience en la matiere (meme pas en C), donc je ne connais pas les procedures pour detecter les locks concurrents.

Rappel: je me tape de ce qu il advient de celui qui se fait kennifier, tant qu un seul script a la fois peut lire et ecrie dans le dit dossier.

La procedure a meme le droit d etre longue: 3, 5, 20 secondes si le server accept des PHP de cette duree.

Je pense que la chose tournera chez free. Mais je ne veux PAS de SQL.
  • # Un ch'tit algo...

    Posté par  . Évalué à 2.

    Lorsque ton script veut ouvrir un fichier (appelons-le file.src),
    il vérifie d'abord la présence d'un fichier nommé file.src.lock.
    Si ce fichier existe, echec.
    Sinon, tu créés le fichier de lock,
    tu fais ce que tu as à faire sur le fichier file.src.
    Quand tu as fini, tu détruis le fichier de lock.
    Fin.
    En espérant que ça aide.
    • [^] # Re: Un ch'tit algo...

      Posté par  (site web personnel) . Évalué à 4.

      Sauf que tu ne résoud rien. Exemple concret :

      A: je vérifie que le .lock existe => il n'existe pas
      B: je vérifie que le .lock existe => il n'existe pas
      A: j'ouvre le .lock en W pour création => ok
      B: j'ouvre le .lock en W pour création => ok, le système écrase
      A: je manipule en croyant être seul => ok
      B: je manipule en croyant être seul => ARGHHH, ce n'est pas le cas
      • [^] # Re: Un ch'tit algo...

        Posté par  (site web personnel) . Évalué à 0.

        merci :)

        j aurais eu du mal a etre aussi calme et explicite que toi.
        • [^] # Re: Un ch'tit algo...

          Posté par  . Évalué à 1.

          Je ne comprends pas pourquoi tu aurais du perdre ton calme.
          Mon post était là pour aider, pas pour faire la leçon. Si j'avais voulu faire la leçon, je m'y serais pris autrement, je n'aurais pas rédigé mon post de cette façon, voire je n'aurais pas posté du tout.
          En ajoutant quelques tests mon algo tiens la route.
          Après tout, si on suit l'explication d'Eric (que je comprend tout à fait par ailleurs), on pourrait modifier l'algo de la sorte (j'ai testé le code php ci-dessous, et ça fonctionne....) :
          #!/usr/bin/php -q
          <?php
          if ((!file_exists ("test.lock") && ('$f=fopen ("test.lock", "w")))
          {
          sleep(10);
          fclose ($f);
          system ("rm test.lock");
          }
          else
          echo "Echec de vérouillage du fichier";
          ?>
          Pour le tester, je l'ai rendu exécutable (appelons-le f1.php), et ai lancé la commande suivante : $ ./f1.php & ./f1.php
          De la sorte, le premier process passe tout de suite en arrière-plan, et rend la main au second.
          J'ai bien le résultat attendu : la première instance créé le fichier de lock, tandis que la seconde m'indique l'impossibilité de créer le vérou. Passé 10 secondes, la première instance me rend la main.
          Si jamais ce script comporte des erreurs, ne perds pas ton calme, hein. J'espère bien profiter de ce post pour comprendre ce qui ne va pas.
          • [^] # Re: Un ch'tit algo...

            Posté par  (site web personnel, Mastodon) . Évalué à 4.

            non il tiens pas la route, car l'opération de test n'est pas atomique.

            c'est les bases de l'exclusion mutuelle.

            je te conseille de lire un peu de doc sur l'exclusion mutuelle et tu comprendras ! (c'est long a expliquer comme ça !)

            M.
            • [^] # Re: Un ch'tit algo...

              Posté par  (site web personnel) . Évalué à 2.

              oui ...

              i je precise dans mon article origiale que j accepte un delai de 20s, c est jutement parce que j avais en tete de:
              - relever l heure
              - stoquer dans le fichier lock le PID du proces courant,
              - attendre 5s
              - relire le lock
              - relever l heure
              - attendre 5s
              - relire le lock
              - vrifier que les 2 valeurs relues sont bien le PID cuorant
              - relever l heure,
              - verifier qu il s est ecoule moins de 13s.

              ce n est absolument pas atomique, mais je pens que ca devrait aire gloalement un lock 'fonctionnel'.

              mais ce serait tellement mieux si le PHP supportait nativement un lock local.
            • [^] # Re: Un ch'tit algo...

              Posté par  . Évalué à 2.

              Ok... J'ai cherché et j'ai au moins trouvé ça http://fr.wikipedia.org/wiki/Mutex(...) (si ça peut aider...).
              Merci pour l'info, je comprend pourquoi ça ne peut pas marcher...
              Si j'ai bien compris ce que j'ai lu et ce que tu as écrit, ça vient du fait que la première partie du test peut être lancée plusieurs fois en même temps, alors que la seconde n'est pas encore effectuée.
              Je pensais, lorsque j'ai écrit ces lignes, que le fait que les tests étaient regroupés dans une seule condition rendait ce test atomique (en tout cas, que la main ne serait pas rendue tant que la fin des tests ne serait pas atteinte). Je m'apperçois maintenant que cette assertion était fausse.
              Loin d'en maîtriser tous les arcanes, j'ai au moins compris, sur la page de wikipedia, je cite : "On ne connait pas, aujourd'hui, d'algorithme parfait - ils sont tous faillibles dans des conditions données.".
              Donc, dans certaines conditions, mon algo, à défaut d'être parfait j'en convient, peut fonctionner sans pour autant faillir.
              Il y a certainement d'autres possibilités qui sont hors de ma portée, je m'en rend bien compte. Désolé pour le dérangement, alors, et merci pour l'info (je me coucherai moins bête ce soir).
          • [^] # Re: Un ch'tit algo...

            Posté par  (site web personnel) . Évalué à 3.

            Même problème.
            A : !file_exists ("test.lock") => ok
            B : !file_exists ("test.lock") => ok
            A : $f=fopen ("test.lock", "w") => ok
            B : $f=fopen ("test.lock", "w") => ok

            et paf, ils sont tout les deux dans la boucle en même temps.

            Le délai entre le test d'existance et l'ouverture est faible mais il existe. Si tu es sur un site Web en charge, rien ne te garantie que rien ne s'y insèrera.

            Quoi que tu fasses, tu auras toujours un test suivi d'une prise de décision. Le problème c'est que rien ne te permet d'être sur qu'un process concurrent ne fera pas le même test après le tien mais avant ta prise de décision.
            Quoi que tu veuilles faire, il te faudra un support de l'OS pour t'assurer un verouillage correct.


            Maintenant tout dépend de ce que tu veux faire. Si c'est pour garantir que tu n'exécutes pas deux compil de kernel simultanément, un vérouillage avec un bête .lock en testant l'existance suffit largement. C'est ce qu'utilisent la plupart des appli pour éviter deux lancements simultanés. Maintenant si tu fais un forum Web assez chargé avec un backend fichier, là il te faudra quelque chose de plus sûr.
            • [^] # Re: Un ch'tit algo...

              Posté par  . Évalué à 2.

              Merci pour cette nouvelle précision. C'est d'ailleurs ce que j'avais compris (post au dessus du tiens au moment où je frappe ce commentaire).
              J'ai commis l'erreur de croire que le fait que le test de l'existence du fichier de vérrou et l'ouverture de ce fichier en écriture soient dans le même bloc entraîne de fait la réalisation de ces deux instructions d'une seule traite, sans interruption.
              Je comprend maintenant d'où vient le problème, d'autant plus si c'est pour une page web.
            • [^] # Re: Un ch'tit algo...

              Posté par  . Évalué à 2.

              Euh, juste pour voir si j'ai bien compris ce qui a été écrit et dit sur le sujet, et surtout pour ma culture personnelle....
              Est-ce qu'un renomage du fichier ne réglerait pas la question ?
              Par exemple :
              if (@rename ("fichier1", "fichier1.lock"))
              traite_fichier1();
              else
              echo "Erreur, impossible d'obtenir un accès à fichier1";

              Je dois certainement me tromper, mais je dis ce que je vois de ce code :
              si je peux renommer fichier1 en fichier1.lock, je traite les commandes que j'ai à faire en mode exclusif, sinon, j'avertis qu'il y a une erreur.
              Evidement, je pense que ça dépend de la fonction de renomage...
              Qu'en pensez-vous ? C'est *_vraiment_* pour ma culture personnelle...
              Merci par avance !
              Ah, oui, j'oubliais de préciser que la fonction traite_fichier1() redonne son ancien nom au fichier avant de sortir....
              • [^] # Re: Un ch'tit algo...

                Posté par  (site web personnel) . Évalué à 2.

                pour ce que j'en sais (donc sous réserve), sous unix, ça a l'air d'être bon.
                Par contre ça veut dire que le fichier est inaccessible en lecture le temps de traitement
                • [^] # Re: Un ch'tit algo...

                  Posté par  . Évalué à 2.

                  Merci. C'est bien ce que j'avais cru comprendre, d'après le dernier commentaire de http://www.php.net/manual/fr/function.rename.php(...)
                  Mais ça me conforte dans mon idée, et ça pourra peut-être servir, pour plus tard.
                • [^] # Re: Un ch'tit algo...

                  Posté par  (site web personnel) . Évalué à 3.

                  je me tape que le fichier ne soit pas lisible,

                  mais ca reste tres interessant:

                  le fait de renommer le fichier, c est le system deficher qui gere l operation atomique: si le renommage marche, alors celui qui peut renomer a tous les droits, et les autre process ne pouvant plus acceder a l original, en deduiront qu un autre processe tourne deja: c est une solutionau probleme pose,

                  mais si on a une pannede courant pendant un traitement, tout mo site va tomber.

                  Je prefere donc pour cette raison l usage de flock decrite plus bas, car apres reboot, les locks seront liberes, enfin j espere.
                  • [^] # Re: Un ch'tit algo...

                    Posté par  . Évalué à 2.

                    Je suis ravi d'avoir pu trouver une solution à un problème posé, même en étant mal parti au départ. Si elle ne te sert pas, ce n'est pas grave. Après tout, ce n'est pas mon problème ;-) !
                    Je voulais juste une précision :
                    je ne sais pas comment fonctionne la fonction flock() en interne, mais elle doit bien poser un indicateur quelque part pour mentionner que tel fichier est vérouillé. Si c'est en mémoire ou avec une gestion de "durée d'un lock", alors ce n'est pas la peine de lire le reste de mon commentaire.
                    Si c'est sur le disque, alors après un reboot, les locks ne seront pas levés. A moins de les effacer à la main, ou qu'ils soient dans /tmp !
                    Du coup, je ne vois pas trop ce qu'apporte flock par rapport à ma solution (non, une fois de plus, je ne cherche pas à vendre ma solution, je cherche simplement à comprendre). Parce que dans mon script, il "suffit" de renommer tous les fichiers truc.lock en truc. Un pauv' script peut faire ça juste avant la reprise du service, sans risquer de mettre les informations en danger. On devrait même pouvoir coller ça dans les scripts d'init, juste avant le lancement d'apache, soyons fous !
                    Bref, je ne cherche qu'à comprendre comment ça fonctionne tout ça. Si quelqu'un peut m'éclairer .... La doc de la fonction flock sur php.net ne m'a pas parrue très claire sur le fonctionnement interne de cette fonction, et je n'ai ni les sources de php, ni de linux sous la main en ce moment pour me jeter dans la doc ou les sources.
                    Merci pour tout.
                    P.S. : j'ai oublié de te remercier pour tes renseignements et ta patience Eric. C'est chose faite !
                    • [^] # Re: Un ch'tit algo...

                      Posté par  (site web personnel) . Évalué à 2.

                      t est gentil mais va vraiment faloire que tu arretes avec tes suspiscions douteuses.

                      si je veux pas utiliser ta methode, c est parce qu en cas de reboot, tout le system tombe ... et comme je ne sais pas quand free reboot un server particulier, c est pas acceptable.

                      Quand a savoir commetn marche le lock, il utilise des fonctions C, et des appels system bas niveau pour acceder a system de fichier, et lui il a le droit a des Mutex propres, et des oprations atomiques avec un noyeau en mode interrompu.
                      • [^] # Re: Un ch'tit algo...

                        Posté par  . Évalué à 4.

                        t est gentil mais va vraiment faloire que tu arretes avec tes suspiscions douteuses.

                        T'es gentil aussi. Tu poses une question, je tente d'y répondre avec mes connaissances, sans aucun sous-entendu.
                        Je m'apperçois que ça ne va pas, on en parle, et j'arrive à un truc qui me plait. Je sais, c'est ta question, mais ne sois pas aussi parano, et prends les choses comme elles sont tapées.
                        Si j'avais un sous-entendu à faire, je te l'enverrais en direct, par le biais de la messagerie interne de linuxfr.
                        Je n'ai pas envie de me prendre la tête avec des gens fiers et imbus de leur personne comme toi. Eric m'a expliqué les choses simplement, je lui en suis reconnaissant.
                        Maintenant, jette ton égo un peu, redescend sur terre et relis mes posts.
                        Il n'y a aucune suspission de quoi que ce soit. Et aucune fiéreté non plus. Juste la joie d'avoir appris quelque chose d'utile et d'intéressant, grâce à Erci, je tiens à le rappeler.
                    • [^] # Re: Un ch'tit algo...

                      Posté par  (site web personnel) . Évalué à 3.

                      à ma connaissance c'est géré par l'OS (donc en mémoire). En fait je n'en sais rien mais je n'ai rien vu sur le disque qui puisse s'y rapporter et je me dis que si c'était géré au niveau disque ça aurait les mêmes défauts que les solutions étudiées plus haut qu'on peut faire nous même au niveau disque.
                      Aucun problème normalement en cas de coupure inopinée du programme (le verrou devrait partir). Ceci dit tu peux tester avec un script PHP et un gros "kill" au milieu, ça évitera que je te fasse faire des bêtises.

                      > Du coup, je ne vois pas trop ce qu'apporte flock par rapport à ma solution

                      Argh, et c'est en répondant que je vois potentiellement le problème de ta solution. En fait le problème ici n'intervient que si tu fais des lectures.

                      Le différence entre flock et ton système c'est que flock pose un verrou même pour la lecture. Le verrou est partagé pour pouvoir faire des lectures simultanées mais il existe, et empêche l'écriture de commencer.

                      Le problème survient dans le scénario suivant (je prend un FS unix comme base, sous win je ne sais pas quel serait la conséquence) :
                      A: commence la lecture
                      B: cherche à commencer l'écriture donc déplace le fichier
                      A: aucun pb sous unix, le fichier ouvert reste accessible, on utilise l'inode à partir de là donc le déplacement n'interfère pas
                      B: modifie le fichier
                      A: continue sa lecture, avec un fichier modifié, potentiellement dans un état intermédiaire (donc non valide) ou non compatible avec le début de la lecture

                      Bref, ton système risque de faire des corruptions si tu fais de la lecture. Si tu ne fais que de l'écriture ça doit aller (sous réserves, comme la première fois). Avec flock le verrou en écriture n'est pas obtenu tant que les lectures ne sont pas finies.

                      > La doc de la fonction flock sur php.net

                      Le flock() utilisé par PHP n'est qu'un wrapper vers le même que tu as en C. Tu peux trouver une doc sommaire dans le man, et probablement plein de trucs dans des bons bouquins de C.

                      > P.S. : j'ai oublié de te remercier pour tes renseignements et ta patience Eric. C'est chose faite !

                      [attention, pub inside] No pb, et si vous aimez y'a un bouquin complet avec plein d'explications du même genre sur la seconde édition de mon livre : http://www.eyrolles.com/Informatique/Livre/9782212116694/livre-php-(...) [/pub]
                      • [^] # Re: Un ch'tit algo...

                        Posté par  (site web personnel) . Évalué à 3.

                        bah, non je vais pas tester un kill violent, parce que de toute facon, ce type de violence peut entrainer 1000 comportements, et Murphy fera qu en test je tomberai sur les cas sympatiques, et en prod, sur les autres.

                        A: continue sa lecture, avec un fichier modifié, potentiellement dans un état intermédiaire (donc non valide) ou non compatible avec le début de la lecture

                        je suis pas d accord; faudrait tester, mais en plus ca depend des drivers du system de fichier. Mon experience est que si un demon lis un fichier, et qu un autre le modifie,remone, deplace ... le premier continura a acceder aux donnees presentes a l instant de son ouverture, meme si les autres effectuent plus tard des ecriture voire des syncs: mon XP prouve que si tu ouvres un truc, tu as le meme resultat si tu le lis immediatement, ou si quelqu un d autre le modifie entre temps.

                        Je parle la de demons locaux, sur un FS local; evidement, des que tu ajoutes NFS, FTP, ou un autre truc, pour alleger les Inodes RAM, les demons reseaux cloent le fihcier apres chaque segment, puis re-ouvren avec un seek, et fatallement, tu obtiens un comportement different. (j ai meme fait l experence avec tftp ... le contenu est mis ajour a chaque trame envoyee ... et sur un reseau a 4mb/s, sur un ficiher de 500ko, tu peux compter les trames une par une.)

                        Quand a savoir comment marche flock, ca depend de la version de PHP, et le serer sur leqel il tourne: entre PHP3 et PHP5, Apache ou Caudium ... j imagine qu y a des differences.
                        • [^] # Re: Un ch'tit algo...

                          Posté par  (site web personnel) . Évalué à 2.

                          > mon experience est que si un demon lis un fichier, et qu un autre le
                          > modifie,remone, deplace

                          sauf erreur de ma part, sous unix :
                          - si quelqu'un renomme, déplace, modifie les permissions : ça n'influe aucunemement sur les fichiers déjà ouverts (l'inode et le contenu ne bougent pas)
                          - si quelqu'un modifie le fichier, tu as potentiellement une modification de ce que tu lis (le contenu peut changer, ça dépend de la présence de flush, du temps d'écriture, de la quantité d'écriture, du cache ...)


                          > entre PHP3 et PHP5, Apache ou Caudium ... j imagine qu y a des differences.

                          Strictement aucune. Il ne s'agit que de l'appel de la fonction C flock. Elle dépend du système, pas de la version de PHP et encore moins du serveur Web. Ou plutot si : elle ne marchera pas sur les serveurs Web trheadés vu que le lock et "par process", mais tu n'en trouveras pas beaucoup des serveurs Web multithread sous Unix.
  • # execlusion mutuelle !!

    Posté par  (site web personnel, Mastodon) . Évalué à 3.

    php à ce qu'il faut pour toi : flock

    http://www.nexen.net/docs/php/annotee/function.flock.php(...)

    M.
    • [^] # Re: execlusion mutuelle !!

      Posté par  (site web personnel) . Évalué à 2.

      http://fr2.php.net/manual/en/function.flock.php(...)

      ouai .... donc, si on reprend mon chemat avec des locks sur fichier, et des pauses ... y a moyen d avoir un jeton exclusif ?

      To acquire an exclusive lock (writer), set operation to LOCK_EX (set to 2 prior to PHP 4.0.1).

      - je capte pas la difference entre shared et non blocking ... quelqu un pour aider ?

      genre:
      - je lock
      - si je perd, je me suicide
      - si je gagne, je fais mon bouleau (qui en fait est peu lie au contenu lui meme)
      - j attend 1s a la fin
      - je libere le lock

      a partir de ce moment la, je pense pas possilbe que deux process puisse travailler en meme temps, si l execution de ma routine interessante depend bien d un lock ...

      la question finale est:
      - chez free, avec des servers distribues, comment ca se passe avec le disques reseau ?
      • [^] # Re: exclusion mutuelle !!

        Posté par  (site web personnel) . Évalué à 2.

        > y a moyen d avoir un jeton exclusif ?

        L'exemple 1 de la doc fait justement ça. Il est exclusif (en gros ton process attend que l'autre ait finit pour jouer à son tour).


        > je capte pas la difference entre shared et non blocking ... quelqu un pour aider ?

        Tu as l'opposition exclusif / partagé (shared) et l'opposition bloquant / non bloquant (non blocking).


        Exclusif c'est quand tu veux un accès unique (généralement pour de l'écriture) : personne d'autre n'a le droit de toucher au fichier quand tu as le verrou exclusif. Partagé c'est généralement pour de la lecture : tu veux bien que plusieurs process lisent le fichier en même temps (pas besoin qu'ils fassent la queue, tu peux obtenir un verrou partagé si quelqu'un en a déjà un) mais pas qu'ils lisent pendant qu'un autre écrit (donc tu ne peux pas obtenir un verrou partagé si quelqu'un en a demandé un exclusif).
        En règle générale tu peux traduire exclusif par "écriture" et partagé par "lecture"

        Bloquant ou non bloquant c'est pour savoir ce que tu fais quand tu ne peux pas avoir le verrou demandé. Le mode bloquant dit "je lis/ecris, j'attendrai le temps qu'il faudra pour ça mais je vais jusqu'au bout". Le mode non bloquant dit "je lis si dispo, sinon j'annule et je reprend la main pour autre chose".


        - écriture non bloquant : j'écris si c'est dispo, j'annule sinon
        $fp = fopen("monfichier", "a") ;
        $libre = flock($fp, LOCK_EX|LOCK_NB) ;
        if (!$libre) {
        fclose($fp) ;
        echo "pas de verrou, on annule et on fait autre chose" ;
        } else {
        fwrite($fp, "ok, j'écris") ;
        fclose($fp) ;
        echo "fichier modifié" ;
        }

        - lecture bloquant : je lis, j'attend le temps qu'il faudra mais je lis
        $fp = fopen("monfichier", "r") ;
        flock($fp, LOCK_SH) ;
        if (!$libre) {
        fclose($fp) ;
        echo "pb d'accès au fichier" ;
        } else {
        $line = fgets($fp, 1024) ;
        fclose($fp) ;
        echo "j'ai lu : $line" ;
        }
        • [^] # Re: exclusion mutuelle !!

          Posté par  (site web personnel) . Évalué à 2.

          c'est mal, j'ai oublié de libérer mes verrous ;)
          rajoutes donc un flock($fp,LOCK_UN); juste avant chaque fclose
          • [^] # Re: exclusion mutuelle !!

            Posté par  (site web personnel) . Évalué à 2.

            derniere question:

            que se passe t il en cas de panne de courant pendant l execution du script ? je veux dire une panne pendant que j ai un lock ?

            le lock est-il materialise par un fichier reel ailleurs (genre /var/tmp), ou est-ce un jeton en RAM qui est perdu au reboot ?

            CA Y EST: j ai enfin mon crontab en ligne en PHP sur mon site perso, et qui depend pas de SQL :)

            - tu charge ton crontab sur ton site
            - a chaque vsite de l index, tu genere un nombre aleatoire,
            - if random()<c then call cron.php

            cron.php: tu lock le fichier 'last.dat'; si il a moins de 1h, tu fais rien.
            si il a plus, tu nettoye tes taches avec du mire laine.

            si y a pas de visite, y a rien a croniser.
            si y a beaucoup de traffic, tu baisse 'c'.

            Vous auriez pas 100 balles ? j ai un brevet logiciel a deposer:
            implementation d un task manager en ligne sur un site web, sans usage d horloge, ni base de donnee.
        • [^] # Re: exclusion mutuelle !!

          Posté par  (site web personnel) . Évalué à 1.

          -2- Tu as l'opposition exclusif / partagé (shared) et l'opposition bloquant / non bloquant (non blocking).

          chui trop bete, et fatigue: j ai bosse la dessus pendant 6 mois en C sur des devices ...
  • # Solutions

    Posté par  (site web personnel) . Évalué à 3.

    3 solutions pour gérer la concurrence coté fichiers :


    1: tu utilises flock() qui est fait pour ça.
    - Attention, ça ne bloque que les process qui vérifient la présence d'un lock avec flock, si quelqu'un accède directement au fichier il réussira.
    - Attention aussi si tu utilises le mode "w" lors du fopen() parce que ça écrasera ton fichier *avant* l'appel à flock(), donc avant de savoir si tu as le droit de le manipuler. Si tu veux utiliser du "w" il faut faire le flock() sur un fichier témoin (genre un .lock vide) et pas sur le fichier cible.

    2: si tes process ne sont pas coopératifs (tu ne peux pas garantir que tout le monde fasse appel à flock) tu peux te reposer sur l'atomicité du déplacement de fichier sous Unix. Tu travailles ton fichier dans un fichier temporaire puis une fois terminé tu le déplace à la destination finale (en écrasant le précédent).
    L'avantage c'est que tu n'as jamais de fichier dans un état corrompu, dans un état intermédiaire, ou de fichier manquant : toute requête de lecture réussira sans défaut. Le désavantage c'est que tu peux avoir plusieurs requêtes d'écriture parallèles. Il y a trois conséquences :
    - tu peux faire bosser ton cpu inutilement (tu lances plusieurs constructions du fichier alors que si tu avais attendu la fin de la construction en cours tu n'aurais pas eu besoin des deux autres). Notes que ce n'est pas gravissime dans pas mal de cas (genre pour une reconstruction de cache c'est souvent acceptable)
    - si deux constructions/modifications se font en parallèles seule une "gagnera" au final. Tu ne peux pas t'en servir pour faire des ajouts à ton fichier (sinon un seul des deux ajouts se fera). Encore une fois, c'est une contrainte tout à fait acceptable si tu reconstruis entièrement le fichier à partir d'une source tierce à chaque fois (genre à partir d'une bdd).
    - si deux constructions/modifications se font en parrallèle, tu n'es pas assuré de laquelle va "gagner" en remplacant le fichier destination en dernier. Il est possible que la construction lancée en premier finisse en dernier, et donc soit celle qui va décider du contenu du fichier destination. Ca par contre ça peut être handicapant, à toi de voir.

    3: tu utilises un sémaphore (oui c'est bourrin, mais ça marche)
    • [^] # Re: Solutions

      Posté par  (site web personnel) . Évalué à 2.

      -1- oui j ai tout mon temps ... docn si je comprends bien, faut utiliser flock sur un acces RO sur un fichier .lock vide ? j irai pecho les exemples sur PHP.net

      vu que moi seul accede a tout, je sius responsable des scripts ... et en l occurence, je respecterai un ptocole connu pour marcher ... donc pas de soucis de double script avec acces concurrentiel sans lock.

      -2- (tu ne peux pas garantir que tout le monde fasse appel à flock)

      si: je suis seul utilisateur pouvant accedr au dit dossier.

      je me pates de perdre du CPU ...
      le probleme n est pas en soit que deux scripst fassent une modif, et qu un travail soit 'perdu', le but est juste d obtenir un lock, et de ne pas commencer DU TOUT la tache si on arrive pas a l avoir:
      le fait de commencer la tahce DOIT ETRE subordonnee a l obtention du lock.

      -3- semaphores ? j en ai entendu parler en C ... aucune idee de ce que c est. c est suppote par PHP ?
      • [^] # Re: Solutions

        Posté par  (site web personnel) . Évalué à 2.

        1- en gros si tu ouvres ton fichier avec "a" ou "r" tu peux faire un flock() directement sur le fichier que tu veux manipuler. Si tu veux l'ouvrir avec "w" tu te met d'accord avec toi même sur un fichier annexe qui ne te sert qu'au verrouillage et tu l'utilise pour flock().
        Ca ressemble à quelque chose du genre (bloquant exclusif):

        $dest = 'monfichier' ;
        $lock = $dest.'.lock' ;
        $fl = fopen($lock, "w") ;
        flock($fl, LOCK_EX) ;
        // à partir de là je suis sûr d'être seul
        $fp = fopen($dest, "w") ;
        // manipulation sur $fp
        fclose($fp) ;
        flock($fl, LOCK_UN) ;
        fclose($fl) ;


        -3- http://fr2.php.net/manual/en/ref.sem.php(...)

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.