6

我的计算机上通常有许多长时间运行的 zsh 进程(分散在各种屏幕会话中),但是一段时间未使用的 shell 往往会被换掉。当我切换到这样一个换出的 shell 并按 enter (在一个空提示符下)时,shell 需要几秒钟才能响应并显示一个新的提示符(但之后它会恢复正常工作)。

为了减少我的烦恼,我想要一个命令(例如unswap PID),我可以调用(从另一个已经响应的 shell)来强制换入 shell。

关于如何实现这一目标的任何想法?

PS我开始四处寻找一个命令来要求系统在任何进程中交换 - 但我没有找到这样的东西,让我相信这是不可能的。我在这里将我的问题集中在zsh,因为这是我真正感兴趣的情况,我希望可能有针对该特定情况的解决方案。如果您有一个更通用的方法适用于任何进程(而不仅仅是 zsh),那也将非常受欢迎。

PPS起初我想在我的 shell 中使用一个陷阱函数,然后它做了一些足以导致 shell 交换的活动(任何事情)。WINCH但是用信号尝试过这个,我发现它不起作用。(也许信号没有传递到换出的进程?有任何信号吗?)


编辑:在我的典型情况下,我有一堆zsh进程正在运行,然后我的浏览器打开(带有多个 Gmail、Facebook 等标签)太久了,导致浏览器囤积所有可用的 RAM 并挤压其他一切都进入交换。桌面有一段时间没有响应,但很快就清理干净了。但是,当重新连接到屏幕会话时,必须手动唤醒每个 shell(通过它们并在每个 shell 中按 enter)。

4

3 回答 3

2

this answer中所述,可以使用gdb转储进程的内存以使其不被交换。

我还发现here有一个gcore脚本可以直接从命令行执行此操作(而不是首先必须启动gdb然后在其中执行其他命令),因此调用:

gcore -o /tmp/SOMETHING PID1 PID2 PID3

将导致具有 PID1、PID2 和 PID3 的程序变为未交换,并将其内容转储到文件/tmp/SOMETHING.PID1/tmp/SOMETHING.PID2

这个答案中还有一个 Python 脚本可以做同样的事情。虽然,诚然——作为对这个问题的回应——以一种更好的方式,因为这个脚本输出了STDOUT我们可以直接通过管道传送到地狱的转储(嗯,我的意思是/dev/null,当然),因为我们只对副作用感兴趣无论如何取消交换。

于 2013-09-06T08:05:32.087 回答
1

由于gcore是一个 shell 脚本,您可以编辑脚本而不是将转储输出保存在文件中,而是保存到文件中/dev/null,例如

#!/bin/sh -u

# Use </dev/null to avoid touching interactive terminal if it is
# available but not accessible as GDB would get stopped on SIGTTIN.
#
exec </dev/null

for pid do
        gdb --nx --batch --readnever \
            -ex "set pagination off" -ex "set height 0" -ex "set width 0" \
            -ex "attach $pid" -ex "gcore /dev/null" -ex detach -ex quit
done

上面确实给出了一个错误Memory read failed for corefile section,但它足以将大部分/所有进程拉入内存并退出交换。

于 2021-11-02T07:21:59.023 回答
0

您是否尝试过/是​​否可以减少内核交换值,以便 zsh 不太可能被换出?

如果您愿意重新编译 zsh,您可以在 main() 中插入对mlockall ( MCL_CURRENT | MCL_FUTURE ) 的调用。这可以防止它首先被换出。

或者添加一个调用mlockall ( MCL_CURRENT ) 后跟munlockall () 的信号处理程序。

于 2013-08-14T15:41:59.533 回答