Clojure est peut-être le plus intéressant de la langue moderne à partir d'un point de vue de la simultanéité. C'est un langage fonctionnel qui prend en charge une variété de différentes techniques de concurrence, y compris:
-
Facile filetée de la simultanéité des capacités sur le filetage des capacités de la machine, mais avec un style fonctionnel
-
Logiciel de transaction de la mémoire pour les mises à jour simultanées d'un état partagé
-
Canal-fonction de simultanéité similaire à l'
Go
langue avec le cœur.async bibliothèque
Facile filetée de la simultanéité
futures
sont utilisés pour déléguer des tâches à d'autres threads.
;; Create and launch a future
(def fut (future (do (Thread/sleep 1000) "Finished!"))))
;; do other stuff while the future does its work
;; Now get the result of the future (waiting for it to complete if needed)
@fut
=> "Finished!"
Logiciel De Transaction De La Mémoire
Une clé de simultanéité fonctionnalité est puissant STM
(logiciel de la mémoire transactionnelle) modèle sans verrouillage de la simultanéité. Cette vidéo sur Clojure de simultanéité est vraiment la peine de prendre un coup d'oeil - il m'a convaincu que Clojure offert quelque chose de véritablement nouveau et spécial.
Comme un avant-goût, voici quelques Clojure de code qui montre comment il est facile d'écrire de façon sûre, fiable, simultanées, transactionnelle code sans verrous à l'aide de la STM sysyem:
;; define two accounts that we want to transfer money between:
(def account-a (ref 1000000))
(def account-b (ref 0))
;; launch 10000 tasks to transfer a random amount of money
;; each of which can happens on a different thread or core
;; each takes place inside a (dosync ....) transaction
(dotimes [i 10000]
(future
(let [transfer (rand-int 10)]
(dosync
(alter account-a - transfer)
(alter account-b + transfer)))))
;; a transactional read of the two accounts should then
;; always have the same total amount, at any point in time
;; (even while the above operation is still running)
(dosync
(+ @account-a @account-b))
=> 1000000
Chaîne En Fonction De La Simultanéité
Cela appuie la "Communication sur les Processus Séquentiels" style de développement, qui a vu récente de l'importance comme une caractéristique fondamentale de l' Go
langage de programmation.
Voici un exemple à partir d'un core.async
exemple qui déclenche simultanément plusieurs requêtes web, compile les résultats et s'applique également timeout logique:
;; get the fastest result from a series of replica queries
(defn fastest [query & replicas]
(let [c (chan)]
(doseq [replica replicas]
(replica c query))
c))
(defn google [query]
(let [c (chan)
t (timeout 80)]
(future (>!! c (<!! (fastest query web1 web2))))
(future (>!! c (<!! (fastest query image1 image2))))
(future (>!! c (<!! (fastest query video1 video2))))
(loop [i 0 ret []]
(if (= i 3)
ret
(recur (inc i) (conj ret (alt!! [c t] ([v] v))))))))
C'est complètement asynchrone (pas les threads sont bloqués!) - de sorte que vous pouvez avoir en toute sécurité des milliers de semblables opérations qui s'exécutent simultanément tout en consommant un minimum de ressources système.