Python multitraitement l'écriture dans un fichier
J'essaye de résoudre un gros problème numérique qui implique beaucoup de sous-problèmes, et je suis en utilisant Python module multiprocessing (plus précisément de la Piscine.carte) pour séparer les différents sous-problèmes indépendants sur différents cœurs. Chaque subproblem implique le calcul de beaucoup de sous-sous-problèmes, et je suis en train de efficacement memoize ces résultats en les stockant dans un fichier si ils n'ont pas été calculé par un processus encore, sinon passer le calcul et il suffit de lire les résultats à partir du fichier.
Je vais avoir des problèmes de concurrence avec les fichiers: différents processus parfois vérifier pour voir si un sous-subproblem a été calculée pour l'instant (en recherchant le fichier où les résultats seraient stockées), de voir qu'il n'a pas, lancer le calcul, puis essayez d'écrire les résultats dans le même fichier en même temps. Comment puis-je éviter d'écrire des collisions de ce genre?
- Découvrez un exemple tiré de la documentation de l'aide de
multiprocessing.Lock
pour synchroniser plusieurs processus. - Vous pourriez avoir un seul processus de l'écriture des résultats, avec une File d'attente en entrée qui pourrait être alimenté par les autres processus de travail. Je crois qu'il serait plus sûr d'avoir tous les processus de travail en lecture seule.
- Je devrais avoir mentionné que, pour compliquer encore les choses, je suis en cours d'exécution à plusieurs gros problèmes principaux dans le même temps sur un cluster, avec chacun l'écriture des résultats à la sous-sous-problèmes sur le même réseau système de fichiers. Donc je peux obtenir des collisions de processus s'exécutant sur des machines distinctes entièrement (donc je ne pense pas que les solutions en utilisant des choses comme le multitraitement.Verrouillage de travail).
- Est le problème que vous rencontrez avec l'écriture des fichiers de collisions, ou est-il juste que vous ne voulez pas reproduire les travaux dans les situations où un travailleur commence la résolution d'un sous-subproblem tandis qu'un autre est déjà au travail sur elle? Ce dernier est un peu plus difficile à résoudre (plus de synchronisation est nécessaire).
- Bien à l'origine, j'avais l'écriture des fichiers de collisions, mais je trouve que la vérification du fichier de l'existence immédiatement avant l'écriture (au lieu de compter sur la case je faire avant de commencer le calcul de la sous-subproblem) a pris soin de cela. Maintenant c'est plus le dernier; je voudrais éviter un double travail, si possible (et peut imaginer d'autres personnes dans la même situation).
- Si votre réseau système de fichiers prend en charge le verrouillage de fichier, vous pouvez utiliser le système d'exploitation de fichier spécifique à la méthode de création exclusivement à créer le fichier et maintenez un verrou exclusif sur elle jusqu'à ce que les résultats sont prêts, puis fermez-le. Tout processus qui n'a pas à "gagner" le créer des la course essayais de l'ouvrir et de ré-essayer (avec un délai) jusqu'à ce que l'ont été en mesure de l'ouvrir, puis ils peuvent lire les résultats.
- Ah, merci JimP! Qui ressemble exactement à ce dont j'ai besoin. Je vais le regarder.
- Vous êtes essentiellement de la programmation d'un serveur de base de données ici. Avez-vous envisagé d'utiliser une existante?
Vous devez vous connecter pour publier un commentaire.
@GP89 mentionné une bonne solution. Utiliser une file d'attente pour envoyer les tâches en écriture à un processus spécifique qui a seul l'accès en écriture au fichier. Tous les autres travailleurs ont accès en lecture seule. Cela permettra d'éliminer les collisions. Voici un exemple qui utilise apply_async, mais il faudra travailler avec la carte trop:
pool.join()
ci-dessouspool.close()
. Sinon, ma travailleurs devraient se terminer avant l'auditeur et le processus serait de tout arrêter.mp.cpu_count() + 2
lors de la définition de nombre de processus?f = open(fn, 'wb')
àf = open(fn, 'w')
pour stocker le résultat, l'autre sage le fichier de sortie sera vide pendant que le code peut fonctionner comme un charme.Il me semble que vous devez utiliser
Manager
pour enregistrer temporairement vos résultats à une liste, puis d'écrire les résultats de la liste dans un fichier. Aussi, l'utilisationstarmap
à passer de l'objet que vous souhaitez traiter et de la gestion de la liste. La première étape consiste à construire le paramètre à passer àstarmap
, qui comprend la liste.À partir de ce point, vous devez décider comment vous allez gérer la liste. Si vous avez des tonnes de RAM et une énorme quantité de données hésitez pas à concaténer à l'aide de pandas. Ensuite, vous pouvez enregistrer des fichiers très facilement au format csv ou un cornichon.