Forum général.cherche-logiciel Accès concurrents, deception windowsienne

Posté par  (site web personnel) .
Étiquettes : aucune
0
7
oct.
2005
Voilà, c'est partie d'une discussion, entre collègues.
On voulais loguer des trucs dans un fichier à partir de pages php (sur un serveur apache/linux). Et un collègue soutenait qu'il fallait gérer des sémaphores pour éviter les accès concurrents.

Du coup, j'ai vite modéliser (en python), un process qui écrit dans un fichier continuellement (test.py)

import sys
for i in range(10000):
fid=open("test.txt","a")
if fid:
fid.write("%d-%s\n" % (i,sys.argv[1]))
fid.close()

et j'en ai lancé plusieurs en même temps (comme ceci : python test.py "nom")

pour vérifier que chaque process a écrit toutes ses lignes, j'ai fait un autre script (verif.py) :

d={}
for i in open("test.txt","r"):
num,nom = i.strip().split("-")
if nom not in d:
d[nom]=[ num]
else:
d[nom].append(num)

for k in d:
print k, len(d[k])


et bien, sous Windows XP (pentium M 1.4), avec 4 process, et 10000 écritures par process ...
il en manquait régulièrement 4 / 5 lignes ...

j'ai été plus que surpris (et j'ai même perdu un pari ;-), je ne m'attendais pas à pouvoir perdre des lignes, et même sur un OS aussi moderne que XP. Et je lui soutenais, que si c'était vraie jadis, à notre époque c'est révolu ! et pourtant ...

Sur la même machine, sous linux (ubuntu), impossible de trouver des louper (même avec plus de process, et même avec plus d'écritures) (et en plus, c'était plus rapide)

On n'a plus de problèmes de logs, et on ne gèrera pas les accès concurrents ;-), car nos pages php tournent sous un linux ;-)
Mais l'experience était assez amusante, pour un vendredi aprem
  • # Ton test me laisse sceptique

    Posté par  . Évalué à 2.

    En effet, qu'est-ce qui te prouve que les process sous Linux on ien tenté d'accéder en même temps sur le même fichier?

    Tu devrais tenter d'écrire tes données via un processus B, pendant qu'un autre processus A a déjà ouvert le fichier en écriture (et attendre la fin du processus A pour écruire tes données via le processus B). Regarde ensuite le résultat ...
  • # ton collègue à raison !

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

    tout est dans le titre :p

    M.
    • [^] # Re: ton collègue à raison !

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

      je m'explique :

      soit le code C suivant :



      #include <stdio.h>
      #include <unistd.h>
      #include <sys/types.h>
      #include <stdlib.h>

      int main(int argc, char**argv) {

      if (argc != 4) {
      printf("Usage: %s file sleep count \n", argv[0]);
      exit(0);
      }

      int i;
      int n = atoi(argv[3]);
      int s = atoi(argv[2]);

      FILE *fp;

      fp = fopen(argv[1], "a");

      if (!fp) {
      printf("Erreur: file '%s'\n", argv[1]);
      exit(0);
      }

      for(i=0; i<n; ++i) {
      fprintf(fp, "je suis le process %d et je fais mon %d ème tour de boucle\n", getpid(), i);
      fflush(fp);
      sleep(s);
      }

      fclose(fp);

      return 0;
      }

      compilation :
      gcc -Wall test.c -o test
      ./test log 1 100 & ./test log 3 50 &
      Execution :

      je suis le process 12184 et je fais mon 0 ème tour de boucle
      je suis le process 12185 et je fais mon 0 ème tour de boucle
      je suis le process 12184 et je fais mon 1 ème tour de boucle
      je suis le process 12184 et je fais mon 2 ème tour de boucle
      je suis le process 12185 et je fais mon 1 ème tour de boucle
      je suis le process 12184 et je fais mon 3 ème tour de boucle
      je suis le process 12184 et je fais mon 4 ème tour de boucle
      je suis le process 12184 et je fais mon 5 ème tour de boucle
      je suis le process 12185 et je fais mon 2 ème tour de boucle
      je suis le process 12184 et je fais mon 6 ème tour de boucle
      je suis le process 12184 et je fais mon 7 ème tour de boucle
      je suis le process 12184 et je fais mon 8 ème tour de boucle
      je suis le process 12185 et je fais mon 3 ème tour de boucle
      je suis le process 12184 et je fais mon 9 ème tour de boucle
      je suis le process 12184 et je fais mon 10 ème tour de boucle
      je suis le process 12184 et je fais mon 11 ème tour de boucle
      je suis le process 12185 et je fais mon 4 ème tour de boucle
      ....
      ....


      CQFD!

      si tu veux des infos sur comment mettre des verrous sur les fichiers en php, regarde du coté de flock : http://www.nexen.net/docs/php/annotee/function.flock.php(...)

      M.
  • # *gruik*

    Posté par  . Évalué à 5.

    >On n'a plus de problèmes de logs, et on ne gèrera pas les accès concurrents ;-),

    Très mauvaise idée. ce n'est pas parce que ca a fonctionné là que ca sera pareil tout le temps.

    - Peux-tu garantir que ca fonctionnera si vous changez de filesystem ?
    - Quid des upgrades de sécu (noyaux et autres) qui peux changer se fonctionnement ? Tu parirais ton salaire dessus ?? :-)
    - ...

    C'est une ressource partagée, elle doit être protégé par un sémaphore ou autre mutex nommé.

    Et puis si c'est des logs, pourquoi ne pas utiliser syslogd qui sait gérer tout çà de façon éprouvée.
    cf http://www.phpbuilder.com/manual/function.syslog.php(...)

    gruikement votre.
  • # syslogd

    Posté par  . Évalué à 4.

    #Voilà, c'est partie d'une discussion, entre collègues.
    # On voulais loguer des trucs dans un fichier à partir de pages
    # php (sur un serveur apache/linux). Et un collègue soutenait qu'il
    # fallait gérer des sémaphores pour éviter les accès concurrents.

    Sous linux, il existe un systhème de journalisation : syslog. Voir la documentation correspondante !

    Sous unix, bien des problèmes d'administration ont déjà été traité et des solutions proposées!

    Pourquoi réinventer la roue ?
    • [^] # Re: syslogd

      Posté par  . Évalué à 3.

      J'ai l'impression que c'est pour pouvoir ne pas y mettre de pneu autour.
      Mais, après, faudra pas s'étonner d'avoir mal au cul...
      • [^] # Re: syslogd

        Posté par  . Évalué à 2.

        Ou aussi la série des log4 : log4j pour java - le premier historiquement, log4net pour C#/.NET, log4cxx pour le C++, log4perl pour le perl, et log4py (http://www.its4you.at/english/log4py.html)(...) pour Python ... Non exhaustif, naturellement.

        C'est assez simple à mettre en place, et tu peux paramétrer le format de sortie tes logs, ainsi que l'endroit où elles sortent, fichier, syslog Unix, gestionnaire d'événements Windows, mail, un serveur réseau, ...

Suivre le flux des commentaires

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