4 votes

Entrée non bloquante en lisp

J'ai un programme qui tourne pendant de longues périodes et je voudrais l'interrompre mais pas avec ctrl-c ctrl-c. Je ne veux pas non plus que le système attende la frappe d'une touche de temps en temps. Au lieu de cela, si j'appuie sur une touche, je veux qu'il termine et quitte. J'ai trouvé listen y read-char-no-hang mais je n'arrive pas à le faire fonctionner correctement. Voici ce que j'ai essayé de faire

(let ((f nil))
  (loop while (not f) do
     (if (listen)
       (setf f t)))))

De toute évidence, cela fait moins qu'un paresseux sous Xanax pour ce qui est de trouver les pressions sur les touches. Qu'est-ce que je fais de mal ?

1voto

Peder Klingenberg Points 4675

CCL dispose du multithreading, je crois. Vous pourriez essayer de créer un fil d'exécution en arrière-plan et de faire en sorte qu'un fil de contrôle effectue une lecture bloquée, puis communique via une variable spéciale. Ce qui suit fonctionne dans Lispworks, je n'ai pas CCL à disposition. Vous devriez traduire la fonction mp:process-run-function en ce que CCL utilise pour créer des threads :

(defparameter *f* nil)
(defun cmd-loop ()
  (setf *f* nil)
  (mp:process-run-function "work" () #'do-work)  ; Spawn worker
  (read-char *terminal-io*)                      ; Blocking read
  (setf *f* t))
(defun do-work ()
  (loop while (not *f*)
        do 
          (format t "~a " *f*)
          (finish-output)))
(cmd-loop)

La grande hypothèse que je fais ici est que le multithreading CCL fonctionne de manière similaire au multithreading LW, de sorte que les deux threads peuvent accéder à la variable d'état partagée. *f* .

0voto

whoplisp Points 1939

J'utilise SLIME pour ces choses. Je lance généralement lisp sur un ordinateur distant comme celui-ci :

whoplisp@laptop:~$ ssh -L4005:127.0.0.1:4005 remotecomputer
whoplisp@remotecomputer:~$ sbcl
(require :asdf)
(require :swank)
(setf swank:*dedicated-output-stream-port* nil)
(swank:create-server)

Je peux alors lancer une session de slime sur l'ordinateur portable depuis emacs :

M-x slime-connect
localhost
4005
C-x C-f /ssh:remotehost:project/test.lisp

Vous devez configurer TRAMP pour que cela fonctionne. Vous devez également vous assurer que vous avez une configuration ssh raisonnable (si vous voulez travailler à distance). Ajoutez ceci à /etc/ssh/ssh_config. Cela accélérera les handshakes pour de nombreuses connexions ssh.

Host remotehost
  ControlMaster auto
  ControlPath /tmp/%r@%h:%p

Cependant, si vous souhaitez simplement faire tourner des choses sur votre machine locale, tout est beaucoup plus facile. Vous pouvez vous reconnecter avec SLIME et utiliser M-x slime-list-threads pour arrêter les travaux que vous avez démarrés plus tôt dans l'image lisp.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X