2013-06-22 7 views
5

Mi piacerebbe eseguire un'espressione in racket speculativamente, sperando di (ma non mi aspetto particolarmente) un risultato. Il mio codice ha un limite di tempo difficile. Esiste un modo semplice per eseguire un po 'di codice della racchetta per alcuni secondi, quindi ucciderlo in modo affidabile ed eseguire il codice di fallback prima che la scadenza scada?Thread di esecuzione della racchetta per un intervallo di tempo fisso

risposta

5

Sì, un modo semplice per farlo è utilizzare la libreria engine. Per esempio:

#lang racket 

(require racket/engine) 

(define e (engine 
      (λ (_) 
      ;; just keep printing every second 
      (let loop() 
       (displayln "hi") 
       (sleep 1) 
       (loop))))) 

;; run only for 2 seconds 
(engine-run 2000 e) 

Invece di specificare un tempo, è anche possibile specificare un oggetto event modo che il filo si arresta quando l'evento attiva.

+0

Non siamo carini con le risposte pubblicate simultaneamente? :) Scherzi a parte, non sapevo nemmeno di "racchetta/motore", è pulito. –

3

È possibile creare un thread "worker" per eseguire il lavoro e un altro thread "watcher" per uccidere il worker.

Questo è descritto nella sezione More: Systems Programming dei documenti.

Il, primo taglio più semplice può essere sufficiente per il calcolo:

(define (accept-and-handle listener) 
    (define-values (in out) (tcp-accept listener)) 
    (define t (thread 
       (lambda() 
       (handle in out) 
       (close-input-port in) 
       (close-output-port out)))) 
    ; Watcher thread: 
    (thread (lambda() 
      (sleep 10) 
      (kill-thread t)))) 

Tuttavia, se hai a che fare con le altre risorse continuate a leggere per conoscere custodi.

+0

Con questo metodo, qual è il modo migliore per restituire il risultato del primo thread fino al thread principale? (thread-send) sembra un po 'sgraziato, tutto ciò che voglio è qualcosa di simile (thread-wait t) che blocca su t e restituisce il risultato. C'è un modo semplice per farlo? – So8res

+0

Buon punto. Potresti provare un ['canale'] (http://docs.racket-lang.org/reference/channel.html) - avere il lavoratore' channel-put' un risultato normale, avere l'osservatore 'channel-put' un risultato timeout, e fare in modo che il thread principale 'channel-get' attenda quello che viene prima. –