7 votes

Accès multithread au même fichier texte

J'ai un énorme fichier texte séparé par ligne et je veux faire des calculs sur chaque ligne. J'ai besoin de faire un programme multithread pour le traiter car c'est le traitement de chaque ligne qui prend le plus de temps à réaliser plutôt que la lecture de chaque ligne. (le goulot d'étranglement se situe au niveau du traitement par le CPU, plutôt qu'au niveau des E/S)

Il y a deux options que j'ai trouvées :

1) Ouvrir le fichier à partir du thread principal, créer un verrou sur l'identifiant du fichier et transmettre l'identifiant du fichier aux threads des travailleurs, puis laisser chaque travailleur accéder directement au fichier en lecture.

2) Créer une configuration producteur/consommateur où seul le thread principal a un accès direct en lecture au fichier, et alimente les lignes à chaque thread de travail en utilisant une file d'attente partagée.

Ce qu'il faut savoir :

  • Je suis vraiment intéressé par les performances de vitesse pour cette tâche.
  • Chaque ligne est indépendante
  • Je travaille en C++ mais je pense que le problème est un peu indépendant du langage.

Quelle option choisiriez-vous et pourquoi ?

5voto

Artem Barger Points 18789

Je suggère la deuxième option, car elle sera plus claire au niveau de la conception et moins compliquée que la première option. La première option est moins évolutive et nécessite une communication supplémentaire entre les threads afin de synchroniser leur progression sur les lignes de fichiers. Alors que dans la deuxième option, vous avez un répartiteur qui s'occupe de l'entrée/sortie et lance les threads des travailleurs pour commencer le calcul, et chaque thread de calcul est complètement indépendant des autres, ce qui vous permet d'évoluer. De plus, dans la deuxième option, vous séparez votre logique de manière plus claire.

1voto

amit Points 74385

Si nous parlons d'un fichier très volumineux, qui doit être traité par un grand cluster - MapReduce est probablement la meilleure solution.

Le cadre vous permet une grande évolutivité et s'occupe déjà de tout le sale boulot de gestion des travailleurs et de tolérance des échecs pour vous.
Le cadre est spécifiquement conçu pour recevoir des fichiers lus à partir d'un système de fichiers [à l'origine, il s'agissait de GFS ] en entrée.

Notez qu'il existe une implémentation open source de map-reduce : Apache Hadoop

0voto

MetallicPriest Points 6372

Si chaque ligne est vraiment indépendante et que le traitement est beaucoup plus lent que la lecture du fichier, ce que vous pouvez faire est de lire toutes les données en une seule fois et de les stocker dans un tableau, de telle sorte que chaque ligne représente un élément du tableau.

Tous vos threads peuvent alors effectuer le traitement en parallèle. Par exemple, si vous avez 200 lignes et 4 threads, chaque thread pourrait effectuer le calcul sur 50 lignes. De plus, comme cette méthode serait d'un parallélisme embarrassant, vous pourriez facilement utiliser OpenMP pour cela.

0voto

Lefteris Points 1630

Je suggère la deuxième option, car elle est nettement meilleure du point de vue de la conception et vous permet de mieux contrôler le travail effectué par les threads de travail.

De plus, cela augmenterait les performances puisque la communication inter-thread dans ce cas est le minimum des deux options que vous avez décrites.

0voto

tristopia Points 5074

Une autre option consiste à mapper le fichier en mémoire et à maintenir une structure partagée gérant correctement l'exclusion mutuelle des threads.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X