【发布时间】:2015-12-06 03:14:09
【问题描述】:
我之前问过this question,关于杀死一个占用过多内存的进程,我已经找到了大部分解决方案。
但是,有一个问题:我尝试使用的方法似乎并未触及计算大量数字。下面的代码旨在对进程设置 10 秒的 CPU 时间限制。
import resource
import os
import signal
def timeRanOut(n, stack):
raise SystemExit('ran out of time!')
signal.signal(signal.SIGXCPU, timeRanOut)
soft,hard = resource.getrlimit(resource.RLIMIT_CPU)
print(soft,hard)
resource.setrlimit(resource.RLIMIT_CPU, (10, 100))
y = 10**(10**10)
当我(在 Unix 机器上)运行这个脚本时,我期望看到的是:
-1 -1
ran out of time!
相反,我没有得到任何输出。我得到输出的唯一方法是使用 Ctrl + C,如果我在 Ctrl + C 之后得到这个10 秒:
^C-1 -1
ran out of time!
CPU time limit exceeded
如果我 Ctrl + C before 10 秒,那么我必须这样做两次,控制台输出如下所示:
^C-1 -1
^CTraceback (most recent call last):
File "procLimitTest.py", line 18, in <module>
y = 10**(10**10)
KeyboardInterrupt
在实验和试图解决这个问题的过程中,我还在打印和大数计算之间放置了time.sleep(2)。它似乎没有任何效果。如果我将y = 10**(10**10) 更改为y = 10**10,那么打印和睡眠语句将按预期工作。在 print 语句中添加 flush=True 或在 print 语句后添加 sys.stdout.flush() 也不起作用。
为什么我不能限制 CPU 时间来计算一个非常大的数字?我该如何解决或至少缓解这个问题?
附加信息:
Python 版本:3.3.5 (default, Jul 22 2014, 18:16:02) \n[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)]
Linux 信息:Linux web455.webfaction.com 2.6.32-431.29.2.el6.x86_64 #1 SMP Tue Sep 9 21:36:05 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
【问题讨论】:
-
我可以在 3.4.3 上重现,但不能在 2.7.9 上重现。这太吓人了。
-
嗯...我总是在我的
Arch Linux 4.2.5-1-ARCH上使用 Python 3.5 在 10 秒之前或之后得到SystemError: PyEval_EvalFrameEx returned a result with an error set。如果我使用 Python 2.7 运行代码,它可以作为您的预期输出正常工作。 -
我猜测 Python 正试图通过预先计算常量来进行优化……结果适得其反。但我没有这方面的证据。
-
@El'endiaStarman:Python 确实 尝试在执行之前预先计算这些常量。在模块
proof.py中写入def f(): return 10**(10**10),然后尝试import proof,然后看着它吃掉你所有的CPU。 -
(相关,虽然没有一个答案真的令人满意:stackoverflow.com/q/24217053)