2010-08-28 3 views
1

Je souhaite lire et écrire des fichiers source Python à partir du système de fichiers de manière thread-safe. Je suppose que ce n'est pas sûr pour les threads, car une requête2 pourrait modifier le fichier avant que request1 ne le charge et ne l'exécute. Je voudrais accomplir quelque chose comme cela un thread attend jusqu'à ce que l'autre thread a écrit, chargé, exécuté et fermé le fichier. Pourquoi faites-vous votre application modifier ses propres fichiers?Django - rendre le thread d'E/S de fichier sûr

+1

Je recommande fortement contre l'importation du code généré dynamiquement cette façon. Au lieu de cela, compilez et exécutez le code directement, avec compile() et exec(). –

Répondre

4

Ce n'est pas seulement incroyablement mal, la métaprogrammation est des ordres de grandeur plus difficile à comprendre le débogage. De plus, python met en cache les modules qu'il importe, donc ce n'est pas vraiment facile de recharger ça. Et, last but not least, vous n'avez pas à écrire le code dans un fichier pour l'exécuter, si vous devez vraiment exécuter du code généré dynamiquement.

Pour répondre à votre question sur l'écriture des fichiers d'une manière thread-safe, la convention générale est:

  • Écrivez votre contenu dans un fichier temporaire sur le même système de fichiers que votre fichier cible.
  • Renommez ce fichier temporaire en fichier cible, en l'écrasant au cours du processus.

Cela fonctionne, car renommer est atomique sur les systèmes POSIX, lorsqu'il est effectué sur le même périphérique. Ainsi, les autres threads/processus auront toujours l'ancien fichier ouvert, qui est maintenant détaché du système de fichiers et sera supprimé dès que ces threads/processus seront terminés, ou ils ouvriront le nouveau fichier avec tout son contenu. Vous évitez d'avoir un fichier à moitié écrit.

En pratique, j'aime créer un répertoire temporaire avec le module tempfile de python, écrire le fichier là-dedans, puis le déplacer et supprimer le répertoire - de cette façon, le fichier est créé avec umask par défaut. Renommer n'est pas vraiment atomique sur Windows, au moins avec les paramètres par défaut, car il ne vous laissera pas écraser votre ancien fichier - vous devez faire deux renommer, et cela introduit une possibilité de course condition. Je ne connais pas une bonne solution pour Windows.

+0

Je veux modifier mes propres fichiers en raison d'une tâche que je dois résoudre que j'ai décrite dans le fil suivant: http://stackoverflow.com/questions/3590166/instantiate-python-class-from-class-available-as -string-only-in-memory Merci pour votre explication. Je vais essayer de le traduire en code. Pas sûr que je suis capable de le faire ;-) Et l'application django ne fonctionne pas sur Windows. –

+0

Recommanderiez-vous encore votre approche pour la tâche de fusion de pdf donnée? –

+1

Cela me semble vraiment sale, et je suis à peu près sûr que l'importation de choses n'est pas vraiment sûre pour les threads. À tout le moins, utilisez le module runpy (http://docs.python.org/library/runpy.html). N'oubliez pas de sauvegarder vos fichiers avec des noms aléatoires, afin que deux threads/processus ne marchent pas sur les orteils de l'autre. Je suis sûr qu'il devrait y avoir un moyen d'exécuter ce code en tant que module sans l'écrire dans le fichier, mais ne trouve rien: le module imp nécessite des fichiers réels, exec ne vous donnera pas de module ... Etes-vous sûr est pas un meilleur moyen dans reportlab de faire la fusion? –

Questions connexes