我在公共IRC机器人中使用this calculator。鉴于Python默认使用任意精度,这将允许任何用户执行calc 10000**10000**10000
或calc factorial(1000000)
之类的操作并有效地“杀死”机器人。
我想知道的是,是否有某种方法可以避免这种情况。我已经尝试将表达式中的所有术语转换为float,但float(factorial(1000000)
仍然需要很长时间才能完成Python解释器,而且我不确定多线程方法是否是正确的方法。< / p>
答案 0 :(得分:2)
不是真正的答案,但我会这样做。您要运行的所有内容都应该在不同的进程中运行。据我所知,不可能限制进程中单个线程的CPU使用率或内存使用量。
也就是说,你必须创建一个新的进程,就像执行用户输入的任务一样,将其写入文件例如。您可以使用fork
执行此操作,使用PID
创建新文件,主进程必须检查,直到子进程终止。一旦进程终止,打开文件“cool_calculator_ [pid] .out”并将其发送回IRC
。
我想这很简单。
然后使用ulimit或其他工具,您可以限制子进程,甚至可以使用主进程终止它们。如果pid
的文件为空,只需回答有错误或其他内容。我想你甚至可以写出一些错误,如超出内存或超出cpu等。
这一切都取决于你想要如何杀死坏的进程。
最后,你的主进程将有工作来生成孩子并在需要时杀死他们并发回答案。
答案 1 :(得分: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()
和{{1函数。
双曲三角函数和radians()
函数抛出exp()
或返回OverflowError
。
inf
函数可以很好地处理大值。
对于简单的算术运算,float cast使函数抛出atan2()
(或OverflowError
)而不是进行计算。
inf
最后,有问题的factorial()函数。我所要做的就是以迭代的方式重新定义函数并将其添加到>>> 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
。
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)
s。
现在我需要弄清楚如何将float()
放在表达式中的所有术语周围,这样就会自动发生。