Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2179 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] [Linux - Debian] read/write named pipe

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] [Linux - Debian] read/write named pipe

n°1928956
rclsilver
Posté le 05-10-2009 à 12:49:35  profilanswer
 

Bonjour,
 
J'ai développé un module apache permettant de créer des hôtes virtuelles (apache2) via un annuaire LDAP. Ainsi, suivant le nom de domaine utilisé, et l'adresse IP (la machine en possède plusieurs), mon module retrouve bien à quel site ce couple DNS/IP correspond, et redirige vers le dossier adéquat.
 
Afin d'améliorer un peu ce module, j'ai souhaité ajouter des statistiques de visite en temps réel. Mon idée est donc qu'à chaque visite sur un des sites, une ligne est écrite dans un tube nommé, puis, dans un autre programme, d'avoir une boucle infini qui lit ce tube nommé, pour finalement insérer ces données dans une base de données.
 
En gros, tout ça fonctionne (enfin presque..). Mon problème, c'est dans mon programme (reader du tube). Voici le petit bout de code qui correspond à la lecture :

Code :
  1. pipe = open(env->named_pipe, O_RDONLY);
  2. if(pipe < 0)
  3. {
  4.  log_append("Impossible d'ouvrir le tube nomme : %s [#%d %s]", env->named_pipe, errno, strerror(errno));
  5. }
  6. else
  7. {
  8.  while(running)
  9.  {
  10.   len = read(pipe, buffer, BUFFER_SIZE);
  11.   log_debug("Retour read() : %d", len);
  12.   if(len > 0)
  13.   {
  14.    /* Je ne fais que traiter les données, absolument rien d'autre */
  15.   }
  16.   else if(len < 0)
  17.   {
  18.    log_append("ERROR Impossible de lire le flux : %s", strerror(errno));
  19.    break;
  20.   }
  21.  }
  22.  close(pipe);
  23.  buckets_close_all();
  24. }
  25. remove_pid_file(env->pid_file);
  26. return 0;


 
Le problème avec ce code, c'est que le read() n'est pas bloquant, et que de ce fait, le programme va utilisé 100% du CPU [pour INFO, quand 100% du CPU est utilisé, read() retourne 0]. J'ai tenté de trouver des solutions avec un select(), mais, malgré avoir mis 0 pour le paramètre "timeout" du select(), le select() n'était pas non plus bloquant.
 
Dans mon module apache, voici le code pour écrire sur le tube nommé :
 

Code :
  1. FILE * f = fopen(conf->mh_stats_output_filename, "a" );
  2. if(!f)
  3. {
  4.  f = stderr;
  5.  perror("fopen" );
  6.  fprintf(f, "Impossible d'ouvrir le tube !\n" );
  7. }
  8. fprintf
  9. (
  10.  f,
  11.  "%s|%s|%d|%ld|%s|%s|%s|%lld|%d\n",
  12.  FORMAT_STR(stats_server_name),
  13.  FORMAT_STR(r->uri),
  14.  r->method_number,
  15.  (long)r->clength,
  16.  FORMAT_STR(r->connection->remote_ip),
  17.  FORMAT_STR(apr_table_get(r->headers_in, "Referer" )),
  18.  FORMAT_STR(apr_table_get(r->headers_in, "User-Agent" )),
  19.  apr_time_sec(r->request_time),
  20.  r->status
  21. );
  22. fflush(f);
  23. if(f != stderr)
  24.  fclose(f);


 
Est-ce que le fait de fermer le flux en écriture à chaque fois peut poser un problème ? De plus voici la version d'apache que j'ai d'installée (je dis surtout ça pour le "mpm-prefork" :

server:~/apache2# dpkg -l | grep apache2
ii  apache2-mpm-prefork       2.2.9-10+lenny3          Apache HTTP Server - traditional non-threaded model
ii  apache2-prefork-dev        2.2.9-10+lenny3          Apache development headers - non-threaded MPM
ii  apache2-utils                  2.2.9-10+lenny3          utility programs for webservers
ii  apache2.2-common          2.2.9-10+lenny3          Apache HTTP Server common files
ii  libapache2-mod-php5       5.2.6.dfsg.1-1+lenny3   server-side, HTML-embedded scripting language (Apache 2 module
ii  libapache2-mod-suphp      0.6.2-3                      Apache2 module to run php scripts with the owner permissions


La version MPM Prefork, si je ne dis pas de bêtise, à chaque requête qui arrive, un "processus" (fork) isolé d'apache se lance, traite la requête et se termine. A priori, mon tube peut donc être ouvert à un instant t par un ou plusieurs instances d'apache, ou à un instant t2 par aucune instance (pas de requête reçue). Est-ce que ce comportement peut être problématique avec les tubes nommés, et est-ce que cela pourrait-être la cause de mon dysfonctionnement sur mon reader ?
 
J'ai choisi comme solution les tubes nommés, mais je suis ouvert à autre chose, si quelque chose est plus approprié pour répondre à mes attentes.
 
Je sais, cela fait beaucoup de questions, de code, ou de lecture tout simplement, mais au moins, tous les éléments sont là pour essayer de trouver la cause, et si possible la solution.
 
Merci beaucoup d'avance.

mood
Publicité
Posté le 05-10-2009 à 12:49:35  profilanswer
 

n°1930382
rclsilver
Posté le 08-10-2009 à 19:01:16  profilanswer
 

Juste pour information (au cas où un jour la réponse intéresse quelqu'un), je suis passé par une autre solution de dialogue entre mes deux applications : client/server udp.

n°1930487
Taz
bisounours-codeur
Posté le 09-10-2009 à 07:56:26  profilanswer
 

...

 

Pourquoi t'as mis un timeout à 0 aussi ...


Message édité par Taz le 09-10-2009 à 07:57:01
n°1930515
rclsilver
Posté le 09-10-2009 à 09:42:09  profilanswer
 

timeout a 0, ça veut dire le select() est bloquant, et dans mon cas, c'est ce que je voulais
 
cf man:
timeout est une limite supérieure au temps passé dans select avant son retour. Elle peut être nulle, ce qui conduit select  à revenir immédiatement. Si le timeout est NULL (aucun), select peut bloquer indéfiniment.
 
Je pense que le timeout nll c'est quand on passe une struct tm avec les tm_sec et tm_usec = 0;
 
Moi, dans mon cas, mon 0, ça correspond à NULL, et donc, d'après le man, le select est bien sensé bloquer

n°1930532
Taz
bisounours-codeur
Posté le 09-10-2009 à 10:05:20  profilanswer
 

Je comprends pas ton problème, y a pas de raison que ton read ne soit pas bloquant. Tu lui as fait quoi à ton fd ?

n°1930533
rclsilver
Posté le 09-10-2009 à 10:10:47  profilanswer
 

je l'ouvre, je select(), je read et ça boucle, donc moi non plus je comprends pas (d'où ma question ici xD). Je pense que le fait que ça soit un tube nommé, ça doit y etre pour quelque chose. j'avoue ne pas avoir testé le code avec un simple fichier


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] [Linux - Debian] read/write named pipe

 

Sujets relatifs
Entiers de taille précise en C++C: addition de grands nombres
[RESOLU]Debutant en C++, petite question a propos d'un programme[matlab/C++] ASA - adaptatibe stimulated annealing
[C] Vider stdin[C++ / DLL]
[C++] Extraction des bits d'un nombrefopen read/write et fseek
Plus de sujets relatifs à : [C] [Linux - Debian] read/write named pipe


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR