2

この計算機をパブリック IRC ボットで使用しています。Python がデフォルトで任意の精度を使用することを考えると、これにより、任意のユーザーがボットのようなものを実行しcalc 10000**10000**10000たりcalc factorial(1000000)、ボットを効果的に「殺す」ことができます。

私が知りたいのは、これを回避する方法があるかどうかです。式のすべての用語を float にキャストしようとしましたが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()関数は、 をスローしOverflowErrorたり、 を返したりしinfます。

このatan2()関数は、大きな値でも問題なく機能します。

単純な算術演算の場合、float キャストにより、関数は計算を行う代わりに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を追加したと思います。

ここで、式のすべての用語を s で囲み、これが自動的に行われるようにする方法を理解する必要がありfloat()ます。

于 2012-07-14T21:26:41.973 に答える