2

我在公共 IRC 机器人中使用这个计算器。鉴于 Python 默认使用任意精度,这将允许任何用户执行类似calc 10000**10000**10000calc factorial(1000000)有效地“杀死”机器人的事情。

我想知道是否有某种方法可以避免这种情况。我已经尝试将表达式中的所有术语都转换为浮动,但float(factorial(1000000)在 Python 解释器中仍然需要很长时间才能完成,而且我不确定多线程方法是否是正确的方法。

4

2 回答 2

2

不是一个真正的答案,但我会这样做。您要运行的所有内容都应该在不同的进程中运行。据我所知,不可能限制进程中单个线程的 CPU 使用率或内存使用率。

也就是说,您必须创建一个新进程,与任务一样执行用户输入的内容并将其写入文件,例如。你可以这样做,使用fork创建一个新文件,PID并且主进程必须检查直到子进程死亡。一旦进程终止,打开文件“cool_calculator_[pid].out”并将其发送回IRC.

我想这很简单。

然后使用 ulimit 或其他工具,可以限制子进程,甚至使用主进程杀死它们。如果文件pid为空,只需回答存在错误或其他问题。我猜你甚至可以写一些错误,比如超出内存或超出 cpu 等。

这完全取决于您要如何杀死不良进程。

最后,您的主进程将负责生成子进程并在需要时杀死它们并发送回答案。

于 2012-07-14T19:52:02.007 回答
1

看起来float()演员阵容毕竟是解决方案。

首先,反三角函数不会在其域之外取值,因此它们是完全安全的,并且可以捕获异常。

>>> acos(5e100)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: math domain error

函数也会发生同样的事情fmod()

“正常”三角函数似乎对大值没有任何问题,除非它们真的很大,这使得函数ValueError再次返回。

舍入函数 (ceil()floor())round()工作正常,inf如果值太大则返回。degrees(), log(), log10(), pow(), sqrt(), fabs(),hypot()radians()函数也是如此。

双曲三角函数和exp()函数 throwOverflowError或 return inf

atan2()功能适用​​于大值。

对于简单的算术运算,浮点转换使函数抛出一个OverflowError(或一个inf)而不是进行计算。

>>> float(10) ** float(100) ** float(100) ** float(1000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: (34, 'Numerical result out of range')
>>> float(5e500) * float(4e1000)
inf

最后,有问题的 factorial() 函数。我所要做的就是以迭代的方式重新定义函数并将其添加到safe_dict.

import sys

def factorial(n):
    fact = 1
    while (n > 0):
        fact = float(fact) * float(n)
        n -= float(1)
        if float(fact) > sys.float_info.max:
            return "Too big"
    return str(fact)

print factorial(50e500)

虽然这是一种非常丑陋且效率极低的阶乘计算方式,但足以满足我的需求。其实我觉得我加了很多不必要float()的s。

现在我需要弄清楚如何将float()s 放在表达式中的所有术语周围,以便自动发生。

于 2012-07-14T21:26:41.973 回答