如何安全地运行不可靠的代码?

时间:2012-03-21 11:13:13

标签: python multithreading debugging logging

假设您正在处理一些您无法信任的恶劣代码,是否有办法安全地运行它而不会失去对脚本的控制?

一个例子可能是一个只在某些时候起作用的功能,并且可能会随机/壮观地失败,你怎么能重试直到它工作?我尝试使用线程模块进行一些黑客攻击,但很难整齐地杀死一个挂起的线程。

#!/usr/bin/env python

import os
import sys
import random

def unreliable_code():

  def ok():
    return "it worked!!"

  def fail():
    return "it didn't work"

  def crash():
    1/0

  def hang():
    while True: 
      pass

  def bye():
    os._exit(0)

  return random.choice([ok, fail, crash, hang, bye])()


result = None
while result != "it worked!!":
  # ???

3 个答案:

答案 0 :(得分:5)

为了安全抵御异常,请使用try / except(但我想你知道)。

为了安全地防止挂起代码(无限循环),我知道的唯一方法是在另一个进程中运行代码。这个子进程可以从父进程中终止,以防它不能很快终止。

为了安全抵御令人讨厌的代码(不应该做的事情),请查看http://pypi.python.org/pypi/RestrictedPython

答案 1 :(得分:4)

您可以尝试在sandbox中运行它。

答案 2 :(得分:4)

在您的实际案例中,您可以切换到多处理吗?请注意,您提出的问题似乎可以通过multiprocessing + threading.Timer + try/except完成。

看看这个:

class SafeProcess(Process):
    def __init__(self, queue, *args, **kwargs):
        self.queue = queue
        super().__init__(*args, **kwargs)
    def run(self):
        print('Running')
        try:
            result = self._target(*self._args, **self._kwargs)
            self.queue.put_nowait(result)
        except:
            print('Exception')

result = None
while result != 'it worked!!':
    q = Queue()
    p = SafeProcess(q, target=unreliable_code)
    p.start()
    t = Timer(1, p.terminate)   # in case it should hang
    t.start()
    p.join()
    t.cancel()
    try:
        result = q.get_nowait()
    except queues.Empty:
        print('Empty')
    print(result)

在一个(幸运的)案例中,我给了我:

Running
Empty
None
Running
it worked!!

在您的代码示例中,您有五分之四的机会获得错误,因此您也可能会产生一个池或其他东西,以提高您获得正确结果的机会。