Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Attendre la fin de l'exécution d'un processus asynchrone

13 réponses
Avatar
Julien Gilli
Bonsoir,

J'essaie, en utilisant emacs lisp et emacs 21, d'exécuter un processus
asynchrone et d'attendre jusqu'à sa terminaison pour récupérer sa sortie
complète.

Pour cela, j'essaie d'utiliser une "sentinele" avec
set-process-sentinel, et une variable globale qui me permet de
déterminer quand l'exécution du processus s'est terminée.

Voici la partie du code concernée :

(defun process-terminated-sentinel (process event)
(message event)
(cond
((not (equal (string-match "finished" event) nil))
(setq process-termination-flag 1))
)
)

(defun x509-decode-cert (cert)
(setq my-new-proc
(start-process "tmp-openssl"
"x509-decode-result"
"openssl" "x509" "-inform" "PEM" "-text" "-noout"))
(process-send-string my-new-proc cert)
(process-send-eof my-new-proc)
(process-send-eof my-new-proc)
(set-process-sentinel my-new-proc 'process-terminated-sentinel)
(setq process-termination-flag 0)
(accept-process-output my-new-proc)
(while (= process-termination-flag 0)
(accept-process-output my-new-proc)
)
(message "process terminated !")
(save-current-buffer
(set-buffer (process-buffer my-new-proc))
(setq output (buffer-string))
(kill-buffer (process-buffer my-new-proc))
)
output
)

La fonction x509-decode-cert prend un certificat au format PEM en entree
(une chaine de caracteres) et renvoie une chaine contenant la sortie de
l'execution de la commande openssl permettant de décoder ce certificat
pour rendre son contenu lisible facilement.

Le comportement que j'obtiens n'est pas celui que j'attends. Il
semblerait que la variable "process-termination-flag" ne soit jamais
modifée, alors que l'évenement "finished" est bien reçu par la
sentinelle : lorsque je presse ctrl-g, le message "finished" apparait
bien dans le mini-buffer.

Si je ne prends pas garde à ce que le processus soit terminé avant de
renvoyer sa sortie, j'obtiens la sortie complète, et je pourrais
considérer que mon code fonctionne. Cependant, le code ne me parait pas
être assez robuste sans utiliser de sentinelle : il serait possible de
renvoyer la sortie partielle du processus avant que ce dernier ne soit
terminé.

Quelle est la bonne façon de récupérer _toute_ la sortie d'une processus
exécuté de manière asynchrone de manière robuste ? Il semblerait que
Xemacs propose une fonction intégrée "process-live-p" qui détermine si
un processus est toujours en cours d'exécution, est-ce qu'une telle
fonctionnalité existe pour Emacs ?

Bonne soirée.

--
Julien Gilli

3 réponses

1 2
Avatar
drkm
Julien Gilli wrote:

drkm wrote:

> Je n'ai pas réellement suivit en détail la discussion, mais
> pourquoi veux-tu utiliser un processus asynchrone dans ce cas ?

Parce qu'il semblerait que ce soit le seul moyen de pouvoir lui envoyer
des données en entrée sans utiliser un fichier temporaire.



Il y a moyen d'envoyer une région en entrée d'un processus
synchrone. Cherche après 'call-process-region' (de mémoire, donc le
nom est peut-être un peu différent). Au pire, tu crée un buffer
temporaire, mais le tout reste très simple :

(with-temp-buffer "*le buffer*"
(insert "bla-bla")
(insert "bla-bla")
(call-process-region ... (point-min) (point-max) ...))

--drkm
Avatar
Julien Gilli
drkm wrote:
Il y a moyen d'envoyer une région en entrée d'un processus
synchrone. Cherche après 'call-process-region' (de mémoire, donc le
nom est peut-être un peu différent). Au pire, tu crée un buffer
temporaire, mais le tout reste très simple :

(with-temp-buffer "*le buffer*"
(insert "bla-bla")
(insert "bla-bla")
(call-process-region ... (point-min) (point-max) ...))




En effet, je n'ai pas encore le réflexe d'utiliser les buffers
temporaires comme des structures de données à part entière, alors
qu'apparemment, c'est un outil de base dont on peut abuser.

Je pense que je vais utiliser cette solution.

Merci !

--
Julien Gilli
Avatar
Xavier Maillard
On 14 Aug 2005, Julien Gilli wrote:

drkm wrote:
> Il y a moyen d'envoyer une région en entrée d'un processus
> synchrone. Cherche après 'call-process-region' (de mémoire,
> donc le nom est peut-être un peu différent). Au pire, tu crée
> un buffer temporaire, mais le tout reste très simple :
> (with-temp-buffer "*le buffer*" (insert "bla-bla") (insert
> "bla-bla") (call-process-region ... (point-min) (point-max)
> ...))
>

En effet, je n'ai pas encore le réflexe d'utiliser les buffers
temporaires comme des structures de données à part entière,
alors qu'apparemment, c'est un outil de base dont on peut
abuser.



J'abonde dans ce sens. Les buffers temporaires sont vraiment une
arme qu'il faut savoir dégainer sans vergogne !
--
Xavier Maillard,
1 2