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

由于我们服务器之前是使用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. MT【124】利用柯西求最值

    已知 \(a\) 为常数,函数\(f(x)=\dfrac{x}{\sqrt{a-x^2}-\sqrt{1-x^2}}\) 的最小值为\(-\dfrac{2}{3}\),则 \(a\) 的取值范围___ ...

  2. 编辑器配置 vscode / Atom / Sublime Text

    vscode配置 https://code.visualstudio.com/docs/languages/cpp https://www.zhihu.com/question/30315894/an ...

  3. 一个非典型的Linux路由配置方案

    上周帮人解决了一个问题,这个问题绝对是非典型性的,采用了非常规的方法.虽然最终的方案非常不符合常规,非常不通用,充满了各种藏得很深的技巧或者说是trick,但是这个问题却是一个学习Linux路由的绝好 ...

  4. 基本数据结构 —— 二叉搜索树(C++实现)

    目录 什么是二叉搜索树 二叉搜索树如何储存数值 二叉搜索树的操作 插入一个数值 查询是否包含某个数值 删除某个数值 测试代码 参考资料 什么是二叉搜索树 二叉搜索树(英语:Binary Search ...

  5. 【BZOJ4820】【SDOI2017】硬币游戏

    Description Solution 设当前走出了一个不匹配任何字符串的串\(S\). ​ 若在\(S\)后随机增添\(m\)个字符,单看这些字符而言,这\(m\)个字符匹配到每个玩家的字符串的概 ...

  6. P3320 [SDOI2015]寻宝游戏 解题报告

    P3320 [SDOI2015]寻宝游戏 题目描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有\(N\)个村庄和\(N-1\)条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以 ...

  7. View的setLayerType() , setDrawingCacheEnabled() 方法用法

    一.Android开发:用getDrawingCache方法获取ImageView中的图像需要注意的问题http://www.linuxidc.com/Linux/2011-09/43131.htm ...

  8. 解题:HDU 4609 Three Idiots

    题面 要求组合的方法显然我们需要对桶卷积,即设$F(x)=\sum\limits_{i=1}^{maxx}x^{cnt[i]}$,然后我们初步的先把$F^2(x)$卷出来,表示选两条边.然后我们发现如 ...

  9. LGP4577【JSOI2018】战争

    题解: 求出$A$ 和$-B$ 的$Minkowsiki$和再$O(logn)$判断一个点是否在凸包内: $Minkowsiki$的求法比较容易忘,要多多温习才可以: #include<bits ...

  10. Fibonacci数列时间复杂度之美妙

    Fibonacci数列: fib(0)=1 fib(1)=1 fib(n)=fib(n-1)+fib(n-2) 上课老师出了一道题,求下列函数的时间复杂度: int fib(int d) { ) ; ...