OVH Cloud OVH Cloud

Thread et fichier

14 réponses
Avatar
PurL
Bonjour,

J'ai une application qui remplit au fil du temps (cadencement régulier) un
fichier "data".
A certains moments prédéfinis, l'application doit exécuter des fonctions
pour exploiter des données que celle-ci a stockée dans "data" tout en
continuant de remplir "data" sans perturber la cadence.

J'ai donc pensé à un thread pour gérer une sorte de file d'attente.
Le point sensible est que ce thread devra, lui aussi, accèder au fichier
"data" (en lecture uniquement).
On est donc face à un probleme de partage de ressources (ici le fichier
"data"), de quelle manière peut on gérer cette affaire ?

Merci pour votre aide,

PurL

4 réponses

1 2
Avatar
Vincent Burel
"Patrick Philippot" wrote in message
news:co1hht$1j5c$
Vincent Burel wrote:

> le flux, c'est mon job, si je te dis que c'est plus facile avec un
> seul thread, c'est que c'est plus facile avec un seul thread, et tu
> aura énormément de mal à démontrer que c'est plus facile avec deux
> thread. D'accord ! ? :-)

Bonjour,

Je laisserai à PurL le soin de déterminer quelle est la meilleure
méthode pour son propre cas. C'est lui ou elle qui fera la démonstration
(que c'est inconfortable, ces pseudos :-) ). Et bien entendu, je
reconnais à chacun le droit d'avoir un avis différent sur les solutions
possibles. Inutile de devenir péremptoire, je reconnais votre droit à la
différence.



ha ! génial, et tellement rare dans la communauté des "programmeurs" ! :-)

Ceci étant, ne mélangeons pas la manière dont le contrôleur hardware
fonctionne et la manière dont les buffers, une fois remplis, sont gérés
au niveau OS et applicatif. Il est *bien évident* que le bras du disque
ne peut pas être au même moment à 2 endroits différents et qu'il y a une
certaine atomicité au niveau des opérations de bas niveau. Cela
n'implique en aucune manière que la gestion logique des données doive
suivre le même schéma.



En aucune manière !? Alors je ne serai pas catégorique sur le sujet, car
l'expérience montre que dans le domaine du flux temps réel, si le haut
niveau respecte les contrainte du bas niveau alors ca marche beaucoup mieux.

Si on part sur le principe d'une boucle monothread qui lit et écrit
alternativement sans discernement ni notion de priorité, la question se
pose bien sûr de savoir à quel endroit on implémente le traitement des
données lues (ou la préparation des données écrites). Si on effectue ce
traitement dans la boucle, la prochaine écriture n'aura lieu qu'une fois
le traitement des données lues terminé (pas de choix: un seul thread -
nécessairement interrompu par d'autres threads du système). Ou
inversement, la prochaine lecture n'aura lieu qu'une fois le traitement
de préparation des données à écrire effectué et après écriture de ces
données.



y'a globalement 2 methodes, ou un seul thread (celui qui s'occupe de la
gestion temps réel des donnée) controle ausi les accès disque, et dans ce
cas ca marche si la bufferisation est large (plusieurs ko). Ou deux thread
distincts, un pour les accès disque et un pour la gestion temps réel , comme
j'ai indiqué dans la réponse que j'ai faite à PURL ce matin.

Si on se contente de lire rapidement (d'alimenter un buffer avec les
données lues) et de redonner tout de suite la main à la passe suivante
pour la lecture, cela veut dire qu'il faut traiter les données lues
séparément dans une structure de type file d'attente... au moyen
(évidemment) d'un thread séparé dédié à ce traitement :-)) .



Exact.

Ça ne
revient pas un peu au même? Encore une fois, il me semble que la donnée
de base est que *la tâche d'écriture est prioritaire par rapport à la
tâche de lecture*. Que PurL me détrompe si ce n'est pas le cas. Dans
cette hypothèse, une implémentation en boucle suffira.



Au final , il fera comme il voudra,

Je ne vois pas en quoi le fait d'utiliser deux threads rend la gestion
de ce mécanisme plus complexe. Au contraire. Avec une synchro
intelligente et une priorité plus grande donnée au thread le plus
critique, j'ai la garantie cette tâche prioritaire sera gérée de manière
efficace, sans être tributaire d'une tâche secondaire de moindre
importance.



un thread pour la lecture et un thread pour l'écriture, le tout sur le même
fichier. ben pour moi, c'est plus compliqué à gérer qu'un seul thread qui
s'occupe des deux. C'est ce que j'ai dit.

Toute cette discussion me rappelle l'époque où Windows n'était pas
multithreads et où les tâches de fond étaient implémentées par le biais
de boucles de messages secondaires. Je ne dis pas que ce n'est pas
encore aujourd'hui le meilleur choix dans certains cas (une économie sur
le nombre de threads dans le système est toujours positive) mais je
n'ai pas le sentiment que cela ait rendu le design des applications plus
clair et plus efficace. Bien au contraire.



Après quand on fait du temps réel, notamment avec de la bufferisation très
courte (<10ms) il faut tenir compte de certaine contraintes du système, pour
mettre en oeuvre une méthodologie ad-hoc. Exemple typique : faire une
acquisition de donnée par buffer de 2ms, et faire une sauvegarde sur Disque
Dur toutes les seconde. D'un coté on aura un thread qui va réveiller le
systeme toutes les 2ms pour lui filer de la donner, de l'autre un autre
thread va se réveillé pour écrire l'équivalent de 1 seconde de flux sur le
disque. Bon ben là, dans certain cas, il se peut que pendant cet accès
disque, le système ne se réveille pas toute les 2ms sur le thread temps
réel, notamment sur les système ou 2ms est inférieur à la granularité de la
préemption, mais aussi sur les systèmes ou le hardware est mal géré (W95,
W98). Sans compter les contraintes hard simple : exemple, le temps de
réaction d'un disque dur IDE est de l'ordre de la milliseconde, voir
plusieurs milliseconde... donc cela veut dire que indépendamment du débit
d'un disque dur, on ne va pas pouvoir dépasser un certain nombre de requète
IDE par seconde. Si vous n'en tenez pas compte dans la méthodologie utilisé
à haut niveau, ben ca ne marchera pas...

A partir du moment ou on fait du flux temps réel, il faut tenir compte du
hard et de comment le système le gère. Et si vous faites confiance au
système pour remettre dans l'odre votre sequence, alors vous ne maitriser
plus grand chose de votre méthodologie de gestion de flux...

VB
Avatar
Vincent Burel
"PurL" wrote in message
news:41a44773$0$9097$
Je vais vous reposer plus concrètement la situation, peut-etre qu'on est


pas
dans la bonne voie :

Déjà je suis embetté par le simple fait que le fichier ouvert (en


écriture)
par la tache d'acquisition m'empeche de l'ouvrir (en lecture) une deuxieme
fois pour la tache d'impression ? en tout cas avec la classe TFileStream


de
BCB5, je vais voir du coté de la fonction C fopen ou la fonction API
OpenFile si c'est pareil...



non, avec OpenFile y'a aucun probleme, éventuellement jouer sur les
FLAG_SHAREREAD, et encore, dans la même APP, je ne pense pas que cela soit
requis.

VB
Avatar
Patrick Philippot
PurL wrote:
- Donc, a chaque heure écoulée, l'application lance une fonction (de
lecture) du fichier contenant les bilans dans lequel elle recherche
dans un premier temps la période à traiter (date de début = heure H -
1, date de fin = heure H) et une fois localisé cette portion de
donnée, lit, traite et imprime.
- sachant que l'acquisition, le calcul des bilans et la sauvegarde
doivent continuer normalement (et restés prioritaire)



Bonjour,

Évidemment, si la tâche de lecture est déclenchée une fois toutes les
heures alors que l'écriture est permanente, ce n'est plus du tout le
même problème.

Dans ce cas, je mettrais en oeuvre la tâche d'acquisition de données
dans un thread séparé qui alimenterait un buffer (l'acquisition de
données étant par essence et dans la plupart des situations, le cas de
figure qui justifie l'utilisation du multithreading) . Votre application
irait régulièrement extraire les données de ce buffer (une structure
FIFO - file d'attente) afin d'alimenter le fichier journal. Quand vous
avez besoin de lire le journal pour sortir un état, vous ouvrez le
fichier journal en lecture et sortez votre bilan. Puis vous repassez en
mode transfert de la file d'attente vers le journal.

Pendant ce temps, le thread d'acquisition a continué d'alimenter la file
d'attente sans interruption (surtout s'il est plus prioritaire que le
reste de l'application). Il suffit simplement que la taille de la file
(qui pourrait dans ce cas être basée sur un MMF) soit calculée de
manière à ce qu'elle ne déborde pas pendant le temps où le mode
journalisation est suspendu pour permettre une édition. Ou bien vous la
retailler quand elle arrive à saturation (ce qui est moins pratique si
c'est un MMF dont la taille est fixe). Mais dans la bibliothèque Borland
ou la bibliothèque STL, il y a bien évidemment de telles structures
prêtes à l'emploi.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Patrick Philippot
Vincent Burel wrote:
A partir du moment ou on fait du flux temps réel, il faut tenir
compte du hard et de comment le système le gère. Et si vous faites
confiance au système pour remettre dans l'odre votre sequence, alors
vous ne maitriser plus grand chose de votre méthodologie de gestion
de flux...



Re,

D'après le dernier message de PurL, nous sommes (très) loin de cette
problématique. J'ai proposé une autre solution.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
1 2