python - 是否可以以编程方式构造Python堆栈框架并在代码中的任意点开始执行?

标签 python serialization stack continuations python-stackless

是否可以在CPython中以编程方式构造一个堆栈(一个或多个堆栈框架)并在任意代码点开始执行?想象以下情况:

  • 您有一个工作流引擎,可以使用一些构造(例如,分支,等待/联接)用Python编写脚本来调用工作流,这些构造称为工作流引擎。
  • 阻塞调用(例如wait或join)在事件调度引擎中使用某种持久性后备存储来设置监听器条件。
  • 您有一个工作流程脚本,该脚本在引擎中调用Wait条件,等待某些条件,稍后再发出信号。这将在事件分配引擎中设置监听器。
  • 工作流脚本的状态以及包括程序计数器(或等效状态)在内的相关堆栈帧得以保留-因为等待条件可能在数天或数月后发生。
  • 在此期间,工作流引擎可能会停止并重新启动,这意味着必须可以以编程方式存储和重建工作流脚本的上下文。
  • 事件调度引擎触发等待条件发生的事件。
  • 工作流引擎读取序列化状态并堆栈,并使用堆栈重建线程。然后,它在调用等待服务的位置继续执行。

  • 问题

    可以使用未经修改的Python解释器完成此操作吗?甚至更好的是,没有人能指出一些可能涵盖此类内容的文档或以编程方式构造堆栈框架并在代码块中间某处开始执行的代码示例吗?

    编辑:为了澄清“未修改的python解释器”,我不介意使用C API(PyThreadState中是否有足够的信息来执行此操作?),但我不想四处查看Python解释器的内部信息并且必须构建一个修改过的版本。

    更新:通过一些初步调查,可以使用PyThreadState_Get()获得执行上下文。这将以PyThreadState(在pystate.h中定义)返回线程状态,该状态在frame中引用了堆栈框架。堆栈帧保存在PyFrameObject定义的structt类型的结构中。 frameobject.h有一个字段PyFrameObject(对bobince而言是一个属性),该字段的程序计数器表示为距代码块开头的偏移量。

    最后这是个好消息,因为这意味着只要保留实际的已编译代码块,就应该能够为尽可能多的堆栈帧重构本地变量,然后重新启动代码。我要说的是,这意味着从理论上讲,无需进行修改的python interpereter,这是可能的,尽管这意味着该代码可能仍将被灵活地紧密地耦合到特定版本的解释器。

    剩下的三个问题是:
  • 事务状态和“saga”回滚,很可能可以通过一种用于构建O/R映射器的元类入侵来实现。我确实曾经构建过一个原型(prototype),所以我对如何实现这一目标有一个很清楚的认识。
  • 稳健地序列化事务状态和任意本地变量。这可以通过读取f_lasti(可从堆栈框架中获得)并以编程方式构造对pickle的调用来实现。但是,我不知道这里可能有什么陷阱。
  • 工作流的版本控制和升级。这有点棘手,因为系统没有为工作流节点提供任何符号 anchor 。我们只有 anchor
    为此,必须标识所有入口点的偏移量并将它们映射到新版本。手动执行可能可行,但我怀疑很难实现自动化。如果要支持此功能,这可能是最大的障碍。

  • 更新2: __locals__(PyCodeObject)在code.h中有一个addr(f_lasti)->行号映射列表(如果在此处出错,请更正)。这可以用于促进将工作流更新到新版本的迁移过程,因为冻结的指令指针可以根据行号映射到新脚本中的适当位置。仍然很凌乱,但更有希望。

    更新3:,我认为答案可能是Stackless Python.。您可以暂停任务并将其序列化。我还没有弄清楚这是否也适用于堆栈。

    最佳答案

    常规Python发行版中包含的expat python绑定(bind)正在以编程方式构造堆栈框架。请注意,它依赖于未公开的私有(private)API。 ta田

    关于python - 是否可以以编程方式构造Python堆栈框架并在代码中的任意点开始执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/541329/

    相关文章:

    带有堆栈变量的 C++ 头文件

    python - 无法加载 dynlib/dll (Pyinstaller)

    python - Matplotlib 3D 图绘制不正确

    python - 调整 QGraphicsItem 中心的大小与鼠标速度成正比?

    圆形缓冲区比。锁定空闲堆栈以实现一个空闲列表

    c - 为什么会出现这些错误?

    python - 从分组数据框中获取百分位数

    php - 什么是数据序列化?

    javascript - 序列化内部 Javascript 对象(如 Range)

    java - Java 的 ObjectOutputStream 的 writeObject() 方法如何用于数组?