我正在试验emacs / ielm中的进程以进行某种并行计算,即为不同的计算启动许多进程,然后等待所有进程终止以组成结果。为此,我设置了以下简单函数:
(defun testp ()
(while (> (length (process-list)) 1)))
我在所有子进程启动后调用testp,当我再次获得控件时,我将结果编写:
我可以请你帮我理解我的错误。
答案 0 :(得分:2)
流程完成后,不一定立即删除。因此(process-list)
可能仍会列出它。用户变量delete-exited-processes
对此进行控制,因此请检查您是否已将其设置为t
。函数list-processes
也将明确删除已完成的进程,因此可能会有所帮助。
有关详细信息,请查看手册中processes的章节。
答案 1 :(得分:2)
Emacs是单线程的,不会处理外部输入(例如关于进程状态的变化),直到达到“安全点”。所以上面的循环(如@juanleon建议的)“太紧”了。您想在其中添加sleep
。
但更好的是使用set-process-sentinel
以便Emacs在进程结束时被告知而不必忙 - 等待它。
E.g:
...start a new process stored in proc...
(push proc my-list-of-running-processes)
(set-process-sentinel proc #'my-run-when-its-over)
...
(defun my-run-when-its-over (proc msg)
(setq my-list-of-running-processes (delq proc my-list-of-running-processes))
(unless my-list-of-running-processes
(message "Haha! all my processes are done!")))
另请注意,您可能不想使用process-list
,因为它可能包含不相关的进程(例如,如果您使用M-x shell
或其他各种事物),这就是我使用{{1}的原因上面。
答案 2 :(得分:0)
也许紧密循环不会让emacs进行适当的进程清理。我的建议是对(process-list)
的结果应用过滤器(因为如果你有一个运行编译,服务器,shell等,进程列表不会为空),过滤掉那些你不同的进程感兴趣,并且还为while
((sleep 0 500)
添加了一小段延迟。