Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asynchronous 由“启动进程”启动的子进程能否比父emacs进程更长寿?_Asynchronous_Emacs_Elisp_Multiprocessing_Parent Child - Fatal编程技术网

Asynchronous 由“启动进程”启动的子进程能否比父emacs进程更长寿?

Asynchronous 由“启动进程”启动的子进程能否比父emacs进程更长寿?,asynchronous,emacs,elisp,multiprocessing,parent-child,Asynchronous,Emacs,Elisp,Multiprocessing,Parent Child,我正在Emacs Lisp中编写一些代码,希望使用start process或类似函数启动子流程。但是,当父emacs进程退出时,我不希望子进程退出。然而,退出父emacs进程似乎也总是杀死所有子进程。以下代码段演示了这一点: (require 'async) (async-sandbox (lambda () (require 'package) (package-initialize) (require 'async) (shell-command "{ echo

我正在Emacs Lisp中编写一些代码,希望使用
start process
或类似函数启动子流程。但是,当父emacs进程退出时,我不希望子进程退出。然而,退出父emacs进程似乎也总是杀死所有子进程。以下代码段演示了这一点:

(require 'async)
(async-sandbox
 (lambda () 
   (require 'package)
   (package-initialize)
   (require 'async)
   (shell-command "{ echo -n 'SPAWNING: '; date; } > ~/temp/ASYNC_LOG")
   (start-process-shell-command "subproc" nil
    "{ echo -n 'STARTED: '; date; } >> ~/temp/ASYNC_LOG;
     sleep 5;
     { echo -n 'FINISHED: '; date; } >> ~/temp/ASYNC_LOG;")
   (shell-command "{ echo -n 'SPAWNED: '; date; } >> ~/temp/ASYNC_LOG")
   (shell-command "sleep 2")
   (shell-command "{ echo -n 'FINISHED WAITING: '; date; } >> ~/temp/ASYNC_LOG")
   ))
此代码同步生成一个emacs进程
(异步沙盒(lambda()…)
,以便我们可以退出该进程以触发问题。然后该进程异步生成一个子进程
(启动进程外壳命令…)
。父进程休眠2秒,而子进程休眠5秒,因此父进程将首先退出。当我运行此代码时,我从未在日志文件中看到“FINISHED”行,这表示子进程在2秒后被终止。如果我将父进程更改为等待7秒,那么我将在输出中看到FINISHED行


那么,有没有类似的方法来启动子进程,这样子进程在其父进程退出时不会被终止?

下面是我如何从dired启动的:

(require 'dired-aux)
(setq dired-guess-shell-alist-user
      '(("\\.pdf\\'" "evince")
        ("\\.eps\\'" "evince")
        ("\\.jpe?g\\'" "eog")
        ("\\.png\\'" "eog")
        ("\\.gif\\'" "eog")
        ("\\.tex\\'" "pdflatex" "latex")
        ("\\.\\(?:mp4\\|mkv\\|avi\\|flv\\)\\'" "vlc")))
(defvar dired-filelist-cmd
  '(("vlc" "-L")))
(defun dired-start-process (cmd &optional file-list)
  (interactive
   (let ((files (dired-get-marked-files t current-prefix-arg)))
     (list
      (dired-read-shell-command "& on %s: " current-prefix-arg files)
      files))) 
  (apply
   #'start-process
   (list cmd nil shell-file-name shell-command-switch
         (format "nohup 1>/dev/null 2>/dev/null %s \"%s\""
                 (if (> (length file-list) 1)
                     (format "%s %s"
                             cmd
                             (cadr (assoc cmd dired-filelist-cmd)))
                   cmd)
                 (mapconcat #'expand-file-name file-list "\" \"")))))

Emacs在终止时所做的是向其派生的进程发送一个信号(我假设它们是那些出现在
进程列表
)中的进程。这种行为在Emacs C代码中是硬编码的(您可以尝试破解进程列表,删除您希望比Emacs寿命长的进程,但我不确定其副作用;它们可能会很难看)

您可以很容易地找到Emacs发送的信号(只需为您的一个进程编写一个信号处理程序),我猜它是SIGHUP,因此进程知道与用户(Emacs)的连接已丢失


你能做的就是让你的进程以一种不会消亡的方式来处理SIGHUP,比如为该信号添加一个处理程序。如果你对该进程代码没有控制权,你可以用一个“nohup”来包装它(这就是@abo abo基本上在做的事情;有关实现细节,请参阅abo abo其他答案)

请问异步日志中的哪一行表示意外行为?
生成:周一11月12:53:25 UTC 2013
开始:周一11月12:53:25 UTC 2013
生成:周一11月12:53:25 UTC 2013
完成等待:周一11月12:53:27 UTC 2013;
完成:周一11月12:53:30 UTC 2013
如果子进程的睡眠时间比父进程长,则不会出现“完成”行,这表示父进程退出时子进程被终止。我将其反转,使父进程睡眠2秒,子进程睡眠5秒,这就是我得到的结果:
生成:周一11月13:28:36 UTC 2013
启动:周一Nov 11 13:28:36 UTC 2013
衍生:Mon 11 13:28:36 UTC 2013
完成:Mon 11 13:28:38 UTC 2013
完成等待:Mon 11 13:28:41 UTC 2013
。我没有使用
(要求“异步)
,我将
异步沙箱
变成了
(交互式)
不使用lambda()的函数。我正在使用OSX Snow Leopard 10.6.8和Emacs Trunk。我的示例已经有父进程休眠2秒,子进程休眠5秒。从您的注释中的时间戳来看,您似乎做了相反的事情。无论如何,如果没有
异步沙盒调用,示例将无法工作,因为关键是要有父进程(由
async sandbox
启动)在子进程(由
start process
启动)之前退出。另一种方法是在
emacs-batch
中运行它,因为async就是这样做的。感谢您帮助我更好地理解这个问题。我已经安装了,并且可以确认您问题中描述的相同行为(使用OSX 10.6.8和相当新版本的emacs Trunk).但是,我还没有解决办法--对不起。