2

私のスクリプトは、Pythonコードの任意の長さと-content文字列を受け入れ、それらをexec()ステートメント内で実行します。任意のコードが実行される時間が所定の制限を超えた場合、exec()ステートメントを終了し、ブール値フラグを設定して、早期終了が発生したことを示す必要があります。

これはどのように達成できますか?

追加情報

これらのコードは、多数のスレッドで並行して実行されます(または、少なくともGILで取得できる限り並行して実行されます)。

別の言語で別の方法がある場合は、試してみます。

システムに誤って損傷を与える可能性のあるもの(ファイルとシステムへのアクセス、インポートステートメント、exec()またはeval()へのネストされた呼び出しなど)へのアクセスを防ぐために、コードをクリーンアップする予定です。

私が検討したオプション

  1. exec()ステートメントはスレッドで実行されているため、ポイズンピルを使用してスレッドを強制終了します。残念ながら、私は毒薬がすべての場合に機能するとは限らないことを読みました。
  2. プロセス内でexec()ステートメントを実行してから、を使用process.terminate()してすべてを強制終了します。しかし、私はWindowsで実行しており、プロセスの作成にはコストがかかる可能性があることを読みました。また、これらすべてを管理しているコードとの通信が複雑になります。
  3. exec()ステートメント内に事前に記述された関数のみを許可し、それらの関数に終了フラグを定期的にチェックさせてから、必要に応じてクリーンアップを実行します。これは複雑で時間がかかり、考慮すべきコーナーケースが多すぎます。もっと簡単な解決策を探しています。

これは、「exec()ステートメントで任意のコードを実行できるようにしたいのはなぜですか?」というちょっと変わった質問に値することを私は知っています。応答のタイプ。私は少し自己進化するコードを試してみています。これが現時点での私の大きな障害です。コードにほとんど何でもできるようにすると、コードが永久にハングする可能性があります。どのようにして制御を取り戻し、制御を取り戻したときにそれを停止しますか?

4

2 に答える 2

3

ここにはいくつかの異なるオプションがあります。

まず、マルチプロセッシングを使用するというjdiの提案から始めます。Windowsプロセスの作成は、実際にはユースケースを破るほどの費用がかからない可能性があります。

それが実際に問題である場合、私が個人的に行うことは、Virtual PC、またはユーザーモードLinuxを使用して、プロセスの作成が安価な別のOSで同じコードを実行することです。そこから無料のサンドボックスも入手できます。

それを望まない場合は、jdiによるプロセスプールの提案はもう少し手間がかかりますが、プロセスを頻繁に強制終了する必要がない限り、うまく機能するはずです。

本当にすべてをスレッドにしたい場合は、ジョブの記述方法を制限できる限り、そうすることができます。ジョブを常にきれいに解くことができる場合は、例外を発生させるだけでジョブを強制終了できます。もちろん、彼らはあなたが提起することを選択した特定の例外を捕らえる必要もありません。明らかに、これらの条件はどちらも汎用ソリューションとしては現実的ではありませんが、ユースケースでは問題ない場合があります。重要なのは、コードエボリューターが手動のリソース管理ステートメント(ファイルの開閉など)を挿入しないようにすることです。ステートメントのみ。(または、openとcloseを挿入しますが、try / finalの中に挿入します。)そして、この方法で作業を行っていない場合でも、たとえば、

コードジェネレーター/エボルバーをさらに制限できる場合は、何らかの形の協調スレッド(たとえば、グリーンレット)を使用できます。これにより、状況がさらに改善されます。

最後に、CPythonから、単一のプロセスで複数のインタープリターインスタンスを実行できる別のPython実装に切り替えることができます。jythonとIronPythonのどちらがそうできるかわかりません。PyPyはそれを行うことができ、制限された環境のサンドボックスもありますが、残念ながら、これらの両方(およびPython 3.xのサポート)はプライムタイムの準備ができていない機能であると思います。つまり、特別なものを入手する必要があります。 PyPyのビルド(おそらくJITオプティマイザーなし)、または自分でビルドします。これは長期的な最善の解決策かもしれませんが、おそらく今日あなたが望んでいるものではありません。

于 2012-06-30T01:09:35.337 に答える
3

これはあまり詳細な回答ではありませんが、コメントに入れたかった以上のものです。

マルチプロセッシングを開始として使用して、タイムアウト付きの関数を作成するためのこの他の質問のようなものを検討することをお勧めします。

スレッドの問題は、スレッドは多くの小さなタスクを処理するワーカーではないため、おそらくポイズン ピルアプローチを使用できないことです。彼らはそこに座って声明をブロックしていました。終了する値を取得することはありません。

あなたは、Windows でプロセスを使用することについての懸念は、それらが高価であることだと述べました。したがって、独自の種類のプロセス プール (プロセスのリスト) を作成することもできます。それらはすべてキューからプルされ、新しいタスクをキューに送信します。いずれかのプロセスがタイムアウトを超えた場合は、そのプロセスを強制終了し、プール内のプロセスを新しいものに置き換えます。こうすることで、タスクごとに新しいプロセスを作成するのではなく、新しいプロセスを作成するオーバーヘッドを、タイムアウトになったときだけに制限できます。

于 2012-06-29T23:27:10.480 に答える