我试图了解如何在 Mac OS X(我有 10.6)的进程中对进程设置资源限制。在 CentOS 上,以下测试程序 (python3.3) 可以正常工作:
import resource
import signal
def confirm(prompt, instructions='(y)es or (n)o only, please.'):
while True:
ok = input(prompt)
if ok in ('y', 'ye', 'yes'):
return True
if ok in ('n', 'no'):
return False
print(instructions)
def handle_cpu_soft_limit(signal, frame):
print('CPU soft limit reached.')
if not confirm('Do you want to continue anyway? (y/n): '):
raise ResourceWarning()
def long_function():
a = 0
while True:
a += 1
a -= 1
def main():
# set soft limit to 1 second, hard limit to 5 seconds (CPU time)
resource.setrlimit(resource.RLIMIT_CPU, (1, 5))
# set handler for soft CPU limit signal
signal.signal(signal.SIGXCPU, handle_cpu_soft_limit)
# do some busy work
try:
long_function()
except ResourceWarning:
print('Stopping now before being forced.')
if __name__ == '__main__':
main()
程序会消耗 CPU 时间,直到达到软限制(1 秒,传递给 的元组中的第一个元素resource.setrlimit()
)。程序捕获操作系统(在本例中为 SIGXCPU)发送的信号并询问我是否要继续。在 CentOS(或其他 Linux)上,如果我说是,它会每隔一秒再次询问我,直到达到硬限制(5 秒),此时操作系统会终止进程。在 Mac OS X 上,我仍然获得并处理 SIGXCPU 信号,但我再也没有收到信号,并且进程永远不会被杀死,即使达到硬限制也是如此。这可能与提问者的经历有关,也可能无关。
setrlimit
Mac OS X 上的手册页说明如下:
资源限制被指定为软限制和硬限制。当超过软限制时,进程可能会收到信号(例如,如果超过 cpu 时间或文件大小),但将允许它继续执行直到达到硬限制(或修改其资源限制)。
…实际上来自 setrlimit 上的 BSD 4.2 手册页。然而,当达到硬限制时,程序似乎永远不会收到 SIGKILL。我在 google 和 SO 上搜索了有关 mac setrlimit 的信息,但没有找到太多有用的信息。我有两个问题:
这种行为(特别是 mac os X 忽略了对进程的硬限制)是否有意并记录在任何地方?我在这里用 python 编写了我的示例,但是在 C 中也发生了同样的事情(我可以根据要求在此处发布一些测试代码),所以这不是语言错误。
有没有办法让这段代码在 linux 和 mac 上表现相同?或者我应该把软限制当作mac上的硬限制吗?