当 control-g 在非常大的文件中不起作用时,如何中断 emacs?

当 control-g 在非常大的文件中不起作用时,如何中断 emacs?

在 Emacs 中查看非常大(例如 128MB)的文件并跳转到文件末尾时,我遇到了某种 O(n^2) 或更糟糕的行为。我认为这可能与我的着色算法有关,该算法根据上下文为文本着色。如果我输入 control-g(键盘退出),操作不会受到影响。我想以某种方式恢复我的 emacs 会话,而不是直接终止它。我尝试发送 SIGINT,但 emacs 刚刚退出。我可以发送任何信号,或者以其他方式(也许在调试器中)强制正在运行的任何操作放弃并将控制权返回给我?

答案1

我怀疑这是字体锁定模式。这可能只对可见部分起作用。它可能正在复制内存中的数据。

sigusr1

sigusr2

这些事件是在 Emacs 进程收到信号SIGUSR1和时生成的SIGUSR2。它们不包含其他数据,因为信号不携带其他信息。它们可用于调试(请参阅错误调试)。

来源:GNU Emacs Lisp 参考手册:其他事件

我不知道它会做什么(或者您正在运行哪个版本的 emacs)但您可以尝试一个可能非破坏性的信号(USR1 或 USR2)。

$ kill -USR1进程号

或者你可以去睡觉,看看它是否恢复。

答案2

这是我对类似问题的回答,希望对您有所帮助:https://stackoverflow.com/a/47070702/3818556


到目前为止,我发现唯一可行的方法是SIGUSR2使用命令行向繁忙的 emacs 进程发送信号kill——无论它是否作为服务器运行(使用--daemon)。这不会强制终止 emacs 进程,但能够中断它正在执行的操作。让我们尝试一个例子来中断sleep-for在 emacs 服务器上运行的循环。(是的,sleep-for可以中断,C-g但这只是一个例子。它工作在一些当 emacs 不响应键盘命令的情况时。)

首先,启动 emacs 服务器,然后使用emacsclient连接到它,输入M-: (sleep-for 120)。现在转到另一个终端并使用命令行找到服务器的进程 ID:ps x|grep 'emacs.*--daemon'。假设我们在这里找到的 PID 是 12345。现在使用终端来打破它:

kill -USR2 12345

现在我们应该看到sleep-for循环中断了。在某些情况下,我需要多次发送此信号。

还请注意,这SIGUSR1不起作用,因此SIGUSR2建议这样做,并且这可能仅适用于高于 v24 的 Emacs 版本。希望这能有所帮助!

答案3

我不知道 emacs 是否进行任何信号处理,但您可以通过放入server-start~/.emacs 文件来使用 Emacs 服务器,这样您就可以在正在运行的 emacs 实例上执行 RPC。

然后,当您想杀死 emacs 并写入时,您可以从 shell 中调用emacsclient -e '(save-buffers-kill-emacs t)'

相关内容