之前遇到一个问题,需要将场景服务这个模块拆分出来,用独立的一个线程去执行。使用独立的线程好处就是,逻辑写的可以相对简单粗暴点,不必考虑到大量的场景服务逻辑卡主线程的情况。

由于我们服务器之前是使用python作为脚本开发,而大家都知道的python有个gil,这意味着并发的线程里只有一个可以获得解释器的全局锁,从而并执行python代码。当然了python这样子也是有原因的,由于其内部使用了大量的静态变量,因此多线程环境下必须有一个线程同步的机制。结果最后选择了在服务器又再嵌入了一个(多个)lua虚拟机,把场景服务用lua来写。

但是,实际上我们是可以做到在一个进程内做到并行的运行多个python虚拟机的,只不过过程稍微曲折一点。基本的思想就是,重复导入多份python动态链接库,每个线程上运行完全独立的python代码

在Linux下就可以通过dlopen运行时动态的导入一个so模块,使用dlmopen则可以重复的导入多份相同的so。dlopen:https://docs.oracle.com/cd/E23824_01/html/821-1465/dlmopen-3c.html#scrolltoc

windows下则不得不在文件系统上保存多份python.dll的实例,并且在运行时通过LoadLibrary分别导入这些dll。LoadLibrary:https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms684175(v=vs.85).aspx

基于上述思路我大致简单实现了一下:

https://github.com/adinosaur/python-vm

有几点要说明的是:

调用Py_Initialize初始化python以及后续调用其它cpython的api必须在同一个线程内,否则在debug版的python中会报没有获得解释器锁而调用cpython api的错误,从而终止程序。

调用动态链接库里的函数这部分代码需要特别注意,虽然在熟知动态连接库使用的调用约定后(比如gcc可能是cdecl,msvc可能是stdcall),是可以将这部分代码写的十分精简通用的。但因为目前我还没做到,因此选择了保守的枚举法:)

linux下使用dlmopen导入多份libpython.so,执行时会有段错误,具体原因尚未查明。因此我的实现中在linux下也是像windows那样,在文件系统中存多份动态链接库的实例。

参考连接:

https://stackoverflow.com/questions/1745975/load-multiple-copies-of-a-shared-library

并行运行多个python虚拟机的更多相关文章

  1. python虚拟机运行原理

    近期为了面试想要了解下python的运行原理方面的东西,奈何关于python没有找到一本类似于深入理解Java虚拟机方面的书籍,找到了一本<python源码剖析>电子书,但是觉得相对来说最 ...

  2. python 虚拟机是单线程;当线程执行I/O密集型操作是,ce

    python 虚拟机是单线程:当线程执行I/O密集型操作是 单核CPU,不存在“并行”,与语言无关:每个线程运行中,其他线程等待该线程让步 粗粒度的并行 靠 软件,细---硬---

  3. python虚拟机中的异常流控制

    异常:对程序运行中的非正常情况进行抽象.并且提供相应的语法结构和语义元素,使得程序员能够通过这些语法结构和语义元素来方便地描述异常发生时的行为. 1.Python中的异常机制: 1.1Python虚拟 ...

  4. Cobra —— 可视化Python虚拟机 and 图解python

    http://blog.csdn.net/balabalamerobert http://blog.csdn.net/efeics/article/category/1486515  图解python ...

  5. 《python源代码剖析》笔记 python虚拟机中的函数机制

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.Python虚拟机在运行函数调用时会动态地创建新的 PyFrameObject对象, 这 ...

  6. Python虚拟机类机制之instance对象(六)

    instance对象中的__dict__ 在Python虚拟机类机制之从class对象到instance对象(五)这一章中最后的属性访问算法中,我们看到“a.__dict__”这样的形式. # 首先寻 ...

  7. Python虚拟机类机制之从class对象到instance对象(五)

    从class对象到instance对象 现在,我们来看看如何通过class对象,创建instance对象 demo1.py class A(object): name = "Python&q ...

  8. Python虚拟机类机制之自定义class(四)

    用户自定义class 在本章中,我们将研究对用户自定义class的剖析,在demo1.py中,我们将研究单个class的实现,所以在这里并没有关于继承及多态的讨论.然而在demo1.py中,我们看到了 ...

  9. Python虚拟机类机制之descriptor(三)

    从slot到descriptor 在Python虚拟机类机制之填充tp_dict(二)这一章的末尾,我们介绍了slot,slot包含了很多关于一个操作的信息,但是很可惜,在tp_dict中,与__ge ...

随机推荐

  1. VUE开发一个图片轮播的组件

    完成效果图如下: vue开发的思路主要是数据绑定,代码如下: <template> <div ref="root" style="user-select ...

  2. 【BZOJ5252】林克卡特树(动态规划,凸优化)

    [BZOJ5252]林克卡特树(动态规划,凸优化) 题面 BZOJ(交不了) 洛谷 题解 这个东西显然是随着断开的越来越多,收益增长速度渐渐放慢. 所以可以凸优化. 考虑一个和\(k\)相关的\(dp ...

  3. yum报错Segmentation fault

    yum install 安装一个包,提示 Segmentation fault,可以确定的是这个源肯定是可用的. 经查询,是 libz 这个库存在多个版本,导致冲突. # ldconfig -v | ...

  4. java线程池赏析

    1.线程池的顶级接口(Executor) 线程池的顶级接口(jdk > 1.5).仅仅定义了方法execute(Runnable). 该方法接收一个Runnable实例,用来执行一个任务,该任务 ...

  5. 解题:SCOI 2012 喵星球上的点名

    题面 初见广义SAM 建立广义SAM,每次把询问走一遍,最终走到节点的子树里的猫老师都被这次点名点到 这样DFS parent树打时间戳记录入栈出栈时间,把问题转化成一个序列问题:给一个若干种颜色构成 ...

  6. k最近邻算法(kNN)

    from numpy import * import operator from os import listdir def classify0(inX, dataSet, labels, k): d ...

  7. hackerrank答案

    regex: https://github.com/taiyang-li/hackerrank/tree/master/hackerrank/regex-exercise awk: https://g ...

  8. sqlalchemy基本使用

    一.ORM介绍 orm英文全称object relational mapping,就是对象映射关系程序,简单来说我们类似python这种面向对象的程序来说一切皆对象,但是我们使用的数据库却都是关系型的 ...

  9. Java poi读取,写入Excel2003

    Java poi读取,写入Excel2003 相关阅读:poi读写Excel2007:http://www.cnblogs.com/gavinYang/p/3576741.htmljxl读写excel ...

  10. c# dev GridControl多选当前行显示样式问题

    由于Dev GridControl在支持多选的时候,如果如果焦点行单独加了样式,Appearance-->FocusedRow  &  HideSelectionRow 这个时候,鼠标焦 ...