Python 可以运行脚本的多个实例,每个实例都包含自己的数据吗?

Can Python run multiple instances of a script with each instance containing it's own data?

本文关键字:实例 包含 自己的 数据 脚本 运行 Python      更新时间:2023-10-16

我正在尝试为游戏引擎设计一个数据结构,并允许脚本语言从中获取数据。由于设计的一些限制,数据需要以类似数据库的结构存储在程序的C++端。主要原因是我不确定Python的序列化库是否能补偿MODER突然添加和删除数据字段的情况。

我想知道是否可以调用python脚本,并让它用自己的数据作为自己的对象?如果没有,您是否可以从C++实例化一个python类,而在运行时之前不知道该类的名称?

您所描述的被称为嵌入Python解释器。CPython适合这种嵌入,并提供了一个关于一些更高级别点的很好的教程(尽管它主要关注扩展而不是嵌入,但大多数概念都与这两个领域相关)。

然而,这种方法有许多缺点。特别是,与C++相比,CPython的速度相当慢。你应该假设执行任意Python字节码会阻塞不合理的时间,除非你已经对它进行了分析,并且知道你可以逃脱惩罚。更糟糕的是,每个Python解释器(一个进程中可以有多个,但需要注意的是)都有一个全局解释器锁(GIL),除非你持有它的GIL,否则你通常无法与Python解释器交互。换句话说,一次只允许一个线程调用给定的Python解释器,这使得用线程管理Python的执行速度变得更加困难。这也意味着,即使Python代码是令人尴尬的并行代码,也可以通过给Python额外的线程来获得的速度奖励。唯一的主要例外是I/O绑定操作,Python通常可以在不持有GIL的情况下执行该操作。

另一个困难是Python对象的类型都是PyObject*。这些是(指向)引用计数对象的指针,具有许多有趣的属性,但关键是,不能只将原始内存直接提供给Python脚本并期望它工作。您至少需要将它封装在array或其他合适的Python对象中。如果您希望底层内存仍然"属于"您的应用程序,您可能希望使用缓冲协议以array和朋友可以使用的标准方式公开此内存(这样您就不会不必要地复制内存)。

在高层,我建议拥有一个或多个专用的Python工作线程(每个解释器一个,并且尽量不要旋转太多解释器,因为它们是重对象),并在这些线程和应用程序的其他部分之间异步传递工作对象。工作线程负责在C++对象和Python对象之间进行转换,保存GIL,并运行慢速Python代码。您还应该记住,Python将消耗与应用程序其他部分使用的计算资源(CPU、内存,也许还有磁盘I/O)相同的计算资源。线程化可能有助于您使用多个内核,但它不会为您购买比实际使用更多的CPU。你可能会发现Python对你的应用程序来说太慢了,这取决于你需要脚本系统的响应能力,以及游戏引擎的其他部分能承受额外的CPU线程带来的性能压力。你应该先构建一个小原型,并验证它是否具有可接受的性能特征,然后再尝试构建真正的东西,或者如果你已经有了一个完整的游戏引擎,试着在它上安装一个最小的Python解释器,并运行一些基准测试。

我从未使用过python。但我认为这是任何编程/脚本语言的主要功能之一:根据需要多次用自己的实例调用函数。