1

我正在 emacs/ielm 中为一种并行计算试验进程,即启动许多进程进行不同的计算,然后等待所有进程终止以组合结果。为此,我设置了以下简单功能:

(defun testp ()
  (while (> (length (process-list)) 1)))

在所有子进程启动后,我调用 testp ,当我再次获得控制权时,我编写结果:

  1. 如果没有子进程 testp 立即退出:ok;
  2. 如果至少有一个子进程 testp 循环:ok;
  3. 当所有子进程都完成后,testp 继续循环,这不好。

我可以请你帮助我理解我错在哪里。

4

3 回答 3

2

Emacs 是单线程的并且在到达“安全点”之前不会处理外部输入(例如关于进程状态的变化)。所以上面的循环(正如@juanleon 建议的那样)“太紧了”。您想在sleep其中添加一个。

但更好的做法是set-process-sentinel让 Emacs 在进程结束时得到通知,而不是忙着等待。例如:

  ...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或其他各种东西),这就是我在my-list-of-running-processes上面使用的原因。

于 2013-09-24T12:54:18.797 回答
2

进程完成后,不一定会立即删除。所以(process-list)可能仍然列出它。用户变量delete-exited-processes对此进行控制,因此请检查您是否已将其设置为t. 该函数list-processes还将显式删除已完成的进程,因此可能会有所帮助。

查看手册中有关流程的章节以获取更多详细信息。

于 2013-09-23T14:49:48.863 回答
0

也许紧密的循环没有让 emacs 进行适当的进程清理。我的建议是对结果应用过滤器(process-list)(因为如果您有正在运行的编译、服务器、shell 等,进程列表不会为空),以过滤掉与您感兴趣的进程不同的进程,并且还可以为while((sleep 0 500)例如)添加一个小延迟。

于 2013-09-23T07:06:19.610 回答