2010-12-30 15 views

risposta

14

Si potrebbe semplicemente iniziare una discussione con una funzione che funziona per sempre.

(defn forever [] 
    ;; do stuff in a loop forever 
) 

(.start (Thread. forever)) 

Se non si desidera che il thread in background per bloccare l'uscita di processo, assicuratevi di farne un thread demone:

(doto 
    (Thread. forever) 
    (.setDaemon true) 
    (.start)) 

Se volete un po 'più finezza è possibile utilizzare il java.util .concurrent.Executors factory per creare un ExecutorService. Ciò semplifica la creazione di pool di thread, utilizza filettature personalizzate, code in entrata personalizzate, ecc.

La lib di claypoole avvolge alcune delle risorse di esecuzione del lavoro in un'API più clojure-friendly se è quello che stai pescando in direzione.

5

mio semplice ordine superiore funzione loop infinito (ricorrendo a future):

(def counter (atom 1)) 

(defn infinite-loop [function] 
    (function) 
    (future (infinite-loop function)) 
    nil) 

;; note the nil above is necessary to avoid overflowing the stack with futures... 

(infinite-loop 
    #(do 
    (Thread/sleep 1000) 
    (swap! counter inc))) 

;; wait half a minute.... 

@counter 
=> 31 

mi consiglia di utilizzare un atomo o uno Clojures altri tipi di riferimento per memorizzare i risultati (come per il contatore nell'esempio precedente).

Con un po 'di regolazione è anche possibile utilizzare questo approccio per avviare/arrestare/sospendere il processo in modalità thread-safe (ad esempio, testare un flag per vedere se (funzione) deve essere eseguita in ogni iterazione del ciclo) .

+2

p.s. anche bello sapere che il sovraccarico di questo approccio è piuttosto minimo - puoi ottenere oltre un milione di incrementi al secondo se togli il thread/sleep – mikera

+0

Un'altra implementazione semplice che non consumerà stack '(defn infinito [f secondi] (futuro (loop [] (f) (Thread/sleep (* secondi 1000)) (ripetizione)))) ' –

+0

@James - la mia implementazione non consuma neanche stack. Il fatto che la chiamata ricorsiva a 'infinito-loop' sia all'interno di un futuro significa che non è ricorrente all'interno dello stack frame della funzione originale. – mikera

Problemi correlati