Bonjour,
Je développe sur une carte embarquée ARM BeagleBoard xM, sur laquelle j'ai installée Debian.
Le système est installé et boot sur une carte MicroSD.
J'ai un programme C qui a des contraintes de temps de réponse de l'ordre des 50ms à respecter.
Lorsque je lance le programme normalement (./prog), mon temps de réponse est toujours respecté.
Cependant lorsque je redirige la sortie stdout du programme vers un fichier pour faire des logs (./prog > log), le programme se bloque de temps en temps (environ une seconde) lorsque le système effectue les écritures disques (sur la carte SD). Car le système effectue les écritures disques du buffer stdout.
Ce sont donc les printf() qui deviennent bloquants lors de ces écritures disque.
Je cherche une solution qui me permettrai de continuer à enregistrer les logs sur le disque, tout en évitant les bloquages causés par les écritures disques.
J'ai pensé a quelques solutions :
utiliser le service rsyslog :
ça ne convient pas car il y'a des printf toutes les 50ms, ca fait beaucoup pour rsyslogmonter un système de fichier ramfs ou tmpfs :
ça ne va pas car j'ai peu de ram...passer par une FIFO dans le programme :
créer un PIPE, envoyer les printf dans ce pipe, et envoyer les données du pipe vers stdout à partir d'un thread,
mais c'est un peu lourdmonter le système de fichier avec l'option "sync"
cela rend l'ensemble du système beaucoup plus lent
Peut-être qu'il existe des solutions plus efficaces, mais je n'en voit pas.
Merci
# Autres pistes
Posté par Achille Fouilleul (site web personnel) . Évalué à 1.
Non testé:
- Essaie plutôt
mount -o async
.-
./prog | tee log > /dev/null
- Si tee est lui-aussi bloquant, tu peux réécrire une variante avec un tampon d'entrée plus grand, mais ça revient un peu au même que la solution à 2 threads.
Tu ne dis rien sur le débit des données produites par ton programme ; s'il dépasse les capacités de la carte SD mais que tu as du temps CPU de disponible, la solution est peut-être de compresser la sortie de ton programme (ex:
./prog | gzip -9 > log.gz
).# non-blocking I/O
Posté par neologix . Évalué à 2.
Tu mets ton FD non-blocking, et avant d'écrire tu appelles select() en le passant dans le writing set: si tu peux écrire, écris, sinon bufferise.
Note que si le taux d'écriture de ton process est assez faible, tu peux utiliser un bête :
$ ./monprog | cat > log
cat va aussi bloquer sur certains write(), mais tant que le pipe n'est pas plein, ton process ne bloquera pas.
Il faut donc grosso modo que :
taux d'écriture < taille PIPE / blocage max de write
(valeurs typiques: taille PIPE = 64KB, blocage max de write ~ 1s avec un BUFSIZ de l'ordre de 8192)
[^] # Re: non-blocking I/O
Posté par MrLapinot (site web personnel) . Évalué à 3.
Ça ne va pas fonctionner : le mode non-bloquant ne marche que pour les tubes (pipes) ou le réseau. Les écritures sur disque sont toujours potentiellement bloquantes, ou pour le dire autrement select te dira toujours « le disque est prêt » (parce qu'effectivement le disque est toujours prêt, il est juste lent).
Il n'existe pas de solution totalement satisfaisante mais les deux approches classiques sont les suivantes :
Dans ton cas, je suppose qu'utiliser les async I/O de POSIX ou mettre en place ton propre thread est la meilleure solution.
# buffers et théorie des files d'attente
Posté par Krunch (site web personnel) . Évalué à 2.
Dans tous les cas, si ton programme génère des données de manière soutenue tel que le récepteur (ta carte SD) ne peut pas suivre, tu vas devoir soit bloquer soit perdre de l'information. Si la vitesse de génération des données est « raisonnable » pour le récepteur sur un temps donné, il suffit d'avoir un buffer en conséquence entre les deux (ce qui peut se faire dans le programme, dans la bibliothèque qui se charge des I/O, avec un programme intermédiaire ou au niveau du noyau).
Après en pratique C10K donne un bon résumé des options possibles sous Unix même si la problèmatique est un peu différente : http://www.kegel.com/c10k.html
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.