J'ai un groupe de tâches de traitement des futures à partir d'une file d'attente qui implique l'écriture dans des fichiers. Quelle est la manière idiomatique de s'assurer qu'un seul futur accède à un fichier particulier à la fois?verrouillage idiomatique de fichier dans clojure?
Répondre
Que diriez-vous d'utiliser des agents au lieu de verrous pour vous assurer cela? Je pense que l'utilisation d'agents pour sauvegarder l'état mutable partagé, que ce soit en mémoire ou sur le disque, est plus idiomatique dans la clojure que l'utilisation de verrous.
Si vous créez un agent à la fois et que vous envoyez les tentatives d'accès aux agents, vous pouvez vous assurer que seul le thread à l'heure accède à un fichier donné.
Par exemple comme ceci:
(use 'clojure.contrib.duck-streams)
(defn file-agent [file-name]
(add-watch (agent nil) :file-writer
(fn [key agent old new]
(append-spit file-name new))))
(defn async-append [file-agent content]
(send file-agent (constantly content)))
puis ajoutez votre dossier par l'agent:
(async-append "content written to file" (file-agent "temp-file-name"))
Si vous avez besoin d'utilisation synchrone du fichier, il pourrait être atteint avec vous attendent. Comme ceci:
(defn sync-append [file-agent content]
(await (send file-agent (constantly content))))
Je ne pense pas qu'il existe une fonction intégrée spécifique pour Clojure, mais vous pouvez utiliser les fonctions d'E/S java standard pour ce faire. Cela ressemblerait à quelque chose comme ceci:
(import '(java.io File RandomAccessFile))
(def f (File. "/tmp/lock.file"))
(def channel (.getChannel (RandomAccessFile. f "rw")))
(def lock (.lock channel))
(.release lock)
(.close channel)
J'ai d'abord vérifié cette avenue, mais malheureusement, cette méthode n'est utile que pour verrouiller le fichier à partir d'autres processus. Lorsque vous travaillez avec plusieurs threads dans la même machine virtuelle, lock et tryLock lancent une exception si un autre thread de la même machine virtuelle a déjà le fichier verrouillé, plutôt que de bloquer jusqu'à ce que le fichier soit disponible. – jhickner
J'utiliser la fonction essentielle Clojure locking qui est utilisé comme suit:
(locking some-object
(do-whatever-you-like))
Ici some-object
pourrait être soit le fichier lui-même, ou encore tout objet arbitraire que vous souhaitez synchroniser sur (ce qui pourrait avoir du sens si vous vouliez un seul verrou pour protéger plusieurs fichiers).
Sous le capot, cela utilise le verrouillage d'objet JVM standard, donc il est fondamentalement équivalent à un bloc de code synchronisé en Java.
- 1. Fonction du mode idiomatique dans Clojure
- 2. Clojure idiomatique pour les rapports de progrès?
- 3. Clojure-façon idiomatique d'initialiser un objet Java
- 4. clojure: façon idiomatique de supprimer la duplication dans un "si"?
- 5. Façon idiomatique pour additionner plusieurs vecteurs dans Clojure
- 6. Clojure idiomatique appelant une fonction de façon conditionnelle
- 7. Clojure idiomatique pour ith et i + 1ème élément de bouclage
- 8. Idiomatique chez Clojure: (drop 1 str) ou (reste str)?
- 9. Itérer de façon idiomatique sur une séquence dimensionnelle de 2 (ou plus) dans Clojure
- 10. Façon idiomatique de "mettre à jour" une clé donnée dans une carte de Clojure?
- 11. Façon idiomatique de construire une structure personnalisée à partir de la fermeture éclair XML dans Clojure
- 12. Log4J verrouillage de fichier
- 13. Façon idiomatique de faire une boucle sur un tableau dans Clojure
- 14. Dans Clojure, est-il idiomatique correct d'utiliser require ... plutôt que d'utiliser ... dans la macro ns
- 15. Verrouillage de fichier Java
- 16. Clojure: Conversion du fichier Clojure en YAML
- 17. Chemin idiomatique pour remplacer (null x) la fonction du Lisp commun dans clojure
- 18. Existe-t-il un moyen plus idiomatique d'obtenir N éléments aléatoires d'une collection dans Clojure?
- 19. Représenter un arbre dans Clojure
- 20. Verrouillage PowerShell Fichier
- 21. fichier de verrouillage en php
- 22. Quelle est la manière idiomatique de capturer des impressions à * sortir * à partir d'une fonction Clojure?
- 23. Quelle est la manière la plus idiomatique de Clojure d'écrire ceci?
- 24. Verrouillage de fichier vs sémaphores
- 25. Verrouillage de fichier en Python?
- 26. Métaprogrammation idiomatique
- 27. Verrouillage d'un fichier téléchargé
- 28. Faire défiler un fichier dans Clojure?
- 29. FTP avec Clojure
- 30. Manière idiomatique d'attendre plusieurs rappels dans Node.js
Neat! Il m'a fallu un peu de temps pour comprendre cela. J'avais fini par utiliser une référence à une carte contenant une entrée pour chaque fichier ouvert. Votre solution semble être beaucoup plus agréable. – jhickner
Je ne suis toujours pas clair sur quelque chose - si deux threads appellent async-append et transmettent le même nom de fichier, comment les empêcher d'ouvrir le fichier? Il semble que l'appel à l'agent de fichier dans async-append créerait un agent unique pour chaque thread, non? – jhickner
Désolé pour les instructions peu claires, je voulais créer un agent de fichier par fichier et l'ajouter soit par async-append ou sync-append selon le besoin de l'ajout asynchrone ou synchrone. Vous pouvez garder les agents eux-mêmes dans une carte pour trouver l'agent correct. –