1. 创建lua虚拟机

lua_State *lua_newstate (lua_Alloc f, void *ud)

创建一个新的独立的lua虚拟机. 参数指定了内存分配策略及其参数, 注意, 让用户可以定制内存分配策略是十分有用的, 比如在游戏服务器端使用lua, 我做过一次统记lua在运行的时候会大量的分配大小小于128字节的内存块, 在这样的环境下, 使用lua原生的分配器就不太适合了, 还好在服务器端, 我们往往已经实现了memory pool, 这时只需要写一个符合 lua_Alloc 原型的适配器, 然后指定为lua的内存分配器就可以了, 很灵活.

从lua的设计层面来说, lua只是内存分配器的用户, 它只使用一个简单的接口来分配内存, 而不去实现如何分配, 毕竟内存分配不在lua的功能范围内, 这样使的lua变的更加紧凑, 它只是专注于实现lua本身, 而不需要去关注内存分配策略这样的和lua本身无关的东西. 其实学习lua源代码不光是为了更好的掌握lua, 也是为了学习lua中的体现出来的一些编程思想, lua是一个高度的一致性的, 优雅的软件作品

失败返回null, 多是因为内存分配失败了

该函数会创建栈

从该函数学习到的东西:  1. 当你制作一个功能时, 最好是理清该功能的核心概念和需求, 然后去实现他们, 功能要模块化, 核心概念之间应该是概念一致的, 联系紧密的[谈何容易, 只能是尽可能的, 随时提醒自己要有这样的想法].

2. 不要因为功能的实现问题而将一个非该功能核心概念的东西加进来, 反之应该把这些东西抽象化作为用户可配置的形式.[在实现时很容易发生"要用到某个功能了, 就是实现它"这样的情况, 这样并不好]就比如lua, 它的核心概念就是lua虚拟机, 而内存分配只是在实现lua虚拟机的过程中的要用到的一种东西, 但它本身不在lua的核心概念里面, 所以把它暴露出来, 让用户自己去定制.

再说下去就是: 除了系统最核心的功能, 其他的东西能用插件的形式暴露给用户, 使其可配置可扩展.

关于这个函数, 还要做更多的解释, 比如我们看到的lua的绝大多数api的第一个参数都是lua_State* L, 而这个L就是lua_newstate制造出来的, 那么在分析源码的时候, 当然要去看看lua_newstate到底是干了些什么, lua_State的结构又是什么, 要了解这些内容, 需要知道lua的内部组织结构, 下面是一张很概括但能反映其结构的图

可以看出来, 在一个独立的lua虚拟机里, global_State是一个全局的结构, 而lua_State可以有多个

值得说明的是, 当调用lua_newstate的时候, 主要的工作就是1. 创建和初始化global_State 2. 创建一个lua_State, 下面来详细的讲解global_State的内容和作用.

global_State

一个lua虚拟机中只有一个, 它管理着lua中全局唯一的信息, 主要是以下功能

1. 内存分配策略及其参数, 在调用lua_newstate的时候配置它们. 也可以通过lua_getallocf和lua_setallocf随时获取和修改它

2. 字符串的hashtable, lua中所有的字符串都会在该hashtable中注册.

3. gc相关的信息. 内存使用统计量.

4. panic, 当无保护调用发生时, 会调用该函数, 默认是null, 可以通过lua_atpanic配置.

5. 注册表, 注意, 注册表是一个全局唯一的table.

6. 记录lua中元方法名称 和 基本类型的元表[注意, lua中table和userdata每个实例可以拥有自己的独特的元表--记录在table和userdata的mt字段, 其他类型是每个类型共享一个元表--就是记录在这里].

7. upvalue链表.

8. 主lua_State, 一个lua虚拟机中, 可以有多个lua_State, lua_newstate会创建出一个lua_State, 并邦定到global_state的主lua_State上.

global_State主要是管理lua虚拟机的全局环境.

lua_State

1. 要注意的是, 和nil, string, table一样, lua_State也是lua中的一种基本类型, lua中的表示是TValue {value = lua_State, tt = LUA_TTHREAD}

2. lua_State的成员和功能

a. 栈的管理, 包括管理整个栈和当前函数使用的栈的情况.

b. CallInfo的管理, 包括管理整个CallInfo数组和当前函数的CallInfo.

c. hook相关的, 包括hookmask, hookcount, hook函数等.

d. 全局表l_gt, 注意这个变量的命名, 很好的表现了它其实只是在本lua_State范围内是全局唯一的的, 和注册表不同, 注册表是lua虚拟机范围内是全局唯一的.

e. gc的一些管理和当前栈中upvalue的管理.

f. 错误处理的支持.

3. 从lua_State的成员可以看出来, lua_State最主要的功能就是函数调用以及和c的通信.

lua_State主要是管理一个lua虚拟机的执行环境, 一个lua虚拟机可以有多个执行环境.

lua_newstate函数的流程

经过上面的分析, 可以看出newstate = [new 一个 global_state] + [new 一个 lua_State], 现在看一下它的流程, 很简单

1. 新建一个global_state和一个lua_State.

2. 初始化, 包括给g_s创建注册表, g_s中各个类型的元表的默认值全部置为0.

3. 给l_s创建全局表, 预分配l_s的CallInfo和stack空间.

4. 其中涉及到了内存分配统统使用lua_newstate传进来的内存分配器分配.

2. 创建新lua执行环境

lua_State *luaE_newthread (lua_State *L)

创建一个新的lua_State, 预分配CallInfo和stack空间, 并共享l_gt表, 注意, 虽然每个lua_State都有自己的l_gt, 但是这里是却将新建的lua_State的l_gt都指向主lua_State的l_gt.

注意, lua_State是lua运行的基础[CallInfo]和与c通信的基础[stack], 在新的lua_State上操作不会影响到原来的lua_State:), 这个是协程实现的基础. 这里顺便提一下协程, 这里先引一段lua创始人的话:" 我们不信任基于抢占式内存共享的多线程技术. 在 HOPL 论文中, 我们写道: "我们仍然认为, 如果在连 a=a+1 都没有确定结果的语言中, 无人可以写出正确的程序." 我们可以通过去掉抢占式这一点, 或是不共享内存, 就可以回避这个问题."协程的基础就是"去掉抢占式, 但共享内存", 这里的共享是在lua虚拟机的层面上的, 而不是通常意义上的share memory, 这里的共享内存直接就指的是不同线程[lua_State]之间, 共享lua_State.l_gt全局表, 全局表可以作为不同协程之间的通信环境, 当然也可以用lua_xmove函数, 协程的事先说到这里.

一个和多lua_State相关的函数是: 在同一个lua虚拟机里传递不同lua_State的值

void lua_xmove (lua_State *from, lua_State *to, int n)
把from栈上的前n个值弹出, 并压入到to栈中.

lua API 小记2的更多相关文章

  1. Lua API 小记1

    这些东西是平时遇到的, 觉得有一定的价值, 所以记录下来, 以后遇到类似的问题可以查阅, 同时分享出来也能方便需要的人, 转载请注明来自RingOfTheC[ring.of.the.c@gmail.c ...

  2. Lua,Lua API,配置文件

    想像一个场景:你的c程序须要有一个窗体,你想让用户能够自己定义窗体大小.方法非常多.比方使用环境变量,或键值对的文件. 无论如何,你须要解析它. 使用lua配置文件是个不错的选择. 首先,你能够定义例 ...

  3. lua API函数大全

    Lua5.1中的API函数 lua_State* luaL_newstate()Lua脚本的编译执行是相互独立的,在不同的线程上执行.通过luaL_newstate()函数可以申请一个虚拟机,返回指针 ...

  4. 【精选】Nginx模块Lua-Nginx-Module学习笔记(一)Nginx Lua API 接口详解

    源码地址:https://github.com/Tinywan/Lua-Nginx-Redis 一.介绍 各种* _by_lua,* _by_lua_block和* _by_lua_file配置指令用 ...

  5. lua api 官方文档 函数后面的方括号 说明 [-0, +0, –]

    本博客注有“转”字样的为转载文章,其余为本人原创文章,转载请务必注明出处或保存此段.c++/lua/windows逆向交流群:69148232 每一个lua api 函数结尾都给出了这样的说明例如: ...

  6. Nginx模块Lua-Nginx-Module学习笔记(一)Nginx Lua API 接口详解

    源码地址:https://github.com/Tinywan/Lua-Nginx-Redis 一.介绍 各种* _by_lua,* _by_lua_block和* _by_lua_file配置指令用 ...

  7. 高并发 Nginx+Lua OpenResty系列(2)——Nginx Lua API

    Nginx Lua API 和一般的Web Server类似,我们需要接收请求.处理并输出响应.而对于请求我们需要获取如请求参数.请求头.Body体等信息:而对于处理就是调用相应的Lua代码即可:输出 ...

  8. (一)chrome扩展 - API小记

    browserAction 设置browser action的badge文字,badge 显示在图标上面 chrome.browserAction.setBadgeText({text:"i ...

  9. DOM BOM 常用API小记

    DOM 1.元素节点: 元素节点element: 更精确的获得元素的标签名(全大写) 属性节点attribute: 属性名 文本节点text: #text 注释节点document:#document ...

随机推荐

  1. 最火的Android开源项目(一)

    摘要:对于开发者而言,了解当下比较流行的开源项目很是必要.利用这些项目,有时能够让你达到事半功倍的效果.为此,CSDN特整理了GitHub上最受欢迎的Android及iOS开源项目,本文详细介绍了20 ...

  2. multiprocessing模块

    multiprocessing模块 由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程. multiproce ...

  3. PhiloGL学习(6)——深情奉献:快乐的一家

     前言 话说上一篇文章结尾讲到这一篇要做一个地球自转以及月球公转的三维动画,提笔,不对,是提键盘开始写的时候脑海中突然出现了几年前春晚风靡的那首歌:蒙古族小丫头唱的快乐的一家.闲言莫提,进入正题.   ...

  4. 如何用java创建一个jdbc程序

    第一个jdbc程序 JDBC简介 Java数据库连接(Java Database Connectivity,JDBC),是一种用于执行SQL语句的Java API,它由一组用Java编程语言编写的类和 ...

  5. C++ 空间配置器(allocator)

    C++ 空间配置器(allocator) 在STL中,Memory Allocator 处于最底层的位置,为一切的 Container 提供存储服务,是一切其他组件的基石.对于一般使用 STL 的用户 ...

  6. Leetcode题解(八)

    26.Remove Duplicates from Sorted Array 题目 直接上代码,方法很简单: class Solution { public: int removeDuplicates ...

  7. HDU 4118 Holiday's Accommodation(树形DP)

    Holiday's Accommodation Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 200000/200000 K (Jav ...

  8. 工控SCADA模型 基于HTML5 Canvas WebGL制作摩托车

    工业方面制作图表,制作模型方面运用到 3d 模型是非常多的,在一个大的环境中,构建无数个相同的或者不同的模型,构建起来对于程序员来说也是一件相当头疼的事情,我们利用 HT 帮大家解决了很大的难题,以下 ...

  9. HTML5与phonegap接口对比

    HTML5与phonegap接口对比 接口 HTML5 phonegap 差异 地理定位 geolocation 单次定位: navigator.geolocation.getCurrentPosit ...

  10. CSS实现父元素半透明,子元素不透明

    CSS实现父元素半透明,子元素不透明. 很久以来大家都习惯使用opacity:0.5在新式浏览器里实现半透明,而对IE较旧的版本使用filter:Alpha(opacity=0.5)的滤镜来实现半透明 ...