+1 au compteur

Répondre
LupusMic
le 25/01/2006 à 16:37
LupusMic
(Bzh) Ça m'étonnerais fort que PHP bloque l'accès à un fichier lorsque tu le lis ou l'écris.
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
Bzh
le 25/01/2006 à 19:02
Bzh
Non, il ne bloque pas, il se met en attente !!! Lorsqu'il veut écrire dans un fichier déja ouvert, il attent que le fichier soit libéré !!!!

C'est justement pour cela que tu ne trouveras pas beaucoup de sources (php) utilisants les locks !!!
LupusMic
le 25/01/2006 à 23:59
LupusMic
J'aime avoir raison, et je vais prouver que j'ai raison sur ce cas. Bien sûr, je prends un cas extrême, volontairement pour pousser PHP dans ces retranchement :

<?php

for($i=0;$i < 100000;$i++)
{
$fp = fopen('counter', 'r+') ;
if(!$fp) break ;

$count = (integer) fread($fp,15) ;
var_dump($count) ;
++$count ;


fseek($fp, 0) ;
fwrite($fp, (string)$count) ;
flush($fp) ;
fclose($fp) ;
}

var_dump($count) ;

?>


J'ai lancé six connexions concurrentes sur le même script (même URL). Si PHP attendait la libération du fichier pour écrire dedant, le nombre finale devrait être 6.000.000.

La chaîne contenue dans le fichier counter est : 1147673. Cette valeur n'a aucune signification, si ce n'est qu'on est bien au dessus 600.000 attendus.

Si l'on observe le contenu du fichier counter, on s'aperçoit que le contenu est complètement délirant, pouvant régresser violemment à une valeur franchement inférieure.

Avec le même source, mais en rajoutant :
flock($fp, LOCK_EX + LOCK_SH) ;

on obtient : 494271.

En consultant la documentation de flock, on s'aperçoit que les applications Web ne sont pas bien codées, ne sont pas correctement portable car flock est obligatoire sous les Microsoft Windows de la branche NT.

Alors maintenant, ma démarche est peut-être erronée, mais j'aimerais qu'on me le prouve ;)

Ce test prouve simplement qu'il n'est pas pertinent de stocker une information issue de sources concurrentes directement dans un fichier.

Je soupçonne le système d'exploitation de tromper PHP lors de l'accès au fichier.

Il faudrait faire le même essai avec MySQL tient.

Le test a été effectué depuis une machine en ADSL vers un serveur dédié Apache2/PHP5, 512 Mo RAM, Athlon XP 2400.
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
Bzh
le 26/01/2006 à 18:06
Bzh
Ah ! wouai... C'est interessant !!!!!

Et quel est l'os de la machine ou tu as testé ton script ???

Je soupsonne une machine microsoft ??? Non ???
Car si j'ai bien compris la doc, obligatoire sous Windows !!!!

Or, il n'est pas indiqué qu'il est obligatoire sous Linux...

Mais c'est très interressant ton teste ! Ce week end je testerai un teste équivalent sur mon local (systeme Debian) !!! On verra...

Mais, si vraiment cela plante, il peut donc être dangereux d'utiliser des fichiers textes or je m'en sert toujours pour des conteurs par exemple. Bien plus rapide qu'un accès à la base de données...

Je vais m'en aller à la pêche aux infos....
Bzh
le 26/01/2006 à 19:04
Bzh
Bon, bin finalement, j'ai pas attendu !!!

Voici comment je m'y suis pris:

=>Os Linux (Debian)
=>Apache
=>Php 5

Le script=>
index.php
<?php

for($i=0;$i < 100000;$i++)
{
$fp = fopen('./counter', 'r+') ;
if(!$fp) break ;

$count = fgets($fp) ;

$count = $count +1;

fseek($fp, 0) ;
fputs($fp, $count ++ );
//flush($fp) ;
fclose($fp) ;
}


?>


Lancement du script une seule fois en même temps=>
100000

Lancement du script deux fois en même temps=>
200000

Lancement du script trois fois en même temps=>
300000

Lancement du script quatre fois en même temps=>
400000

Lancement du script cinq fois en même temps=>
500000

Lancement du script six fois en même temps=>
600000

Une remarque c'est que le script se termine EXACTEMENT dans le même ordre que l'exécution !!!

Le 1 en premier, puis le 2 et le 3 etc...

Ils se terminent dans le même ordre. Et le résultat est sans surprise...

Je pense que cela montre bien que php gère tout seul les locks. Les scripts sont mis en attente tant qu'ils n'ont pas accès au fichier. Tout en gardant leur ordre d'arrivé...

Maintenant, je suis curieu pour ton résultat. Si tu pouvais donner plus d'infos ce serait cool...

Bye...
Lefounard
le 26/01/2006 à 19:24
Lefounard
Salut,
La discussion est vive mais rien ne sert de se prendre autant la tete !
La doc indique :
PHP dispose d'un système complet de verrouillage de fichiers. Tous les programmes qui accèdent au fichier doivent utiliser la même méthode de verrouillage pour qu'il soit efficace.

Note : flock() est obligatoire sous Windows.

Comme d'hab c'est toujours mieux sous Windows ;)
Ciao,
I am singing in the rain , I am happy again !!
Bzh
le 26/01/2006 à 19:46
Bzh
Tous les programmes
Là je ne comprends pas, il parle des programmes qui tournent sur la machine ? Ou bien seulement des scripts php ???

Donc, c'est bien ce qui me semblait, php, à lui seul, gère très bien les accès fichiers...
Lefounard
le 26/01/2006 à 19:48
Lefounard
Si on precise qu'il obligatoire sous windows, ca veut tout simplement dire que sous unix, le flock est facultatif, et donc qu'il est geré automatiquement et integrer dans PHP !
Voila c tout !
Ciao,
I am singing in the rain , I am happy again !!
Bzh
le 26/01/2006 à 20:59
Bzh
Encore un manque de Windows qu'il est nécessaire de combler manuellement... En gros...

Bye...
LupusMic
le 29/01/2006 à 16:44
LupusMic
C'est vrai que j'ai oublié de marquer l'OS sur lequel j'ai fais le tests :p Ben c'est une Debian GNU/Linux Sarge, avec les paquets Dotdeb.

Mais ça me paraissait aussi curieux que le lock ne marchait pas correctement. Je dois avoir un problème de configuration ou pire : un bogue de PHP ou de la libc :o)

Je précise que j'utilise SuExec, c'est peut-être le vilain qui casse tout ?

Je vais enquêter...
Développeur récurrent, procédural et relationnel. Caustique soupe-au-lait.
Répondre
LoadingChargement en cours