Python 可以运行脚本的多个实例,每个实例都包含自己的数据吗?
Can Python run multiple instances of a script with each instance containing it's own data?
我正在尝试为游戏引擎设计一个数据结构,并允许脚本语言从中获取数据。由于设计的一些限制,数据需要以类似数据库的结构存储在程序的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。但我认为这是任何编程/脚本语言的主要功能之一:根据需要多次用自己的实例调用函数。
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 使用包含互斥锁的类的方法实例化 cpp11 线程
- 如何使用包含内部类的类实例有效地从内部类访问成员?
- 如何为包含另一个类实例的数组制作常量 getter?
- 包含不同大小静态数组的类的多个实例
- 在C++中,为什么仅包含与其基类实例的联合的派生类占用的内存多于联合的大小?
- 无法编译包含"if constexpr"的函数模板实例化
- 如何操作包含"unique_ptr"的类的实例?
- 包含另一个实例的特征实例,该实例持有固定大小的特征对象
- 包含iostream时的自定义类时间的错误实例
- 如何正确创建一个包含由不同类的实例组成的联合的类?
- 编译的程序是否有可能不包含实例化的模板类
- 在头文件中包含std::vector会导致模板实例化错误
- Python 可以运行脚本的多个实例,每个实例都包含自己的数据吗?
- 为什么在操纵函数名称中包含C 功能模板实例的返回类型
- 模板类包含对其自身实例的引用的 stdvector
- 正在重试包含同一异常的exception_ptr的多个实例
- 如何在给定包含类的实例的情况下实例化嵌套类
- 交换包含非一般可复制类型的“std::aligned_storage”实例-未定义的行为
- c++规范是否允许非虚类的实例包含虚值表指针的内存?