在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一、Lua脚本语言
1. 概述 Lua是一种脚本编程语言,与一般脚本语言不同,被称为是嵌入式的脚本语言。Lua最著名的应用是在暴雪公司的网络游戏魔兽世界中。 Lua语言可以独立进行编程,但这不是其主要的使用方式。Lua最典型的用法,是作为一个库,嵌入到其他大型语言(称为宿主语言)的应用程序之中,为应用程序提供参数配置或逻辑描述等功能,带来前所未有的灵活性。
Lua常见的宿主语言有:C/C++、Java、.NET,甚至脚本语言如PHP、Ruby。 2. Lua与相似解决方案的比较
Lua体积很小,往往使用静态链接嵌入到程序内部,在发布应用时不需要附带任何的运行时支持。
3. 宿主语言中嵌入Lua的工作流程
(1)宿主语言建立Lua解释器对象
(2)将宿主语言实现的Lua扩展,如函数等,注册到Lua解释器中,供其使用。
(3)读入Lua源程序或预先编译好的Lua程序。
(4)执行读入的Lua程序。
二、Lua虚拟机的初始化
Lua工作的核心是Lua虚拟机,宿主语言在加载和执行Lua脚本时,做的第一件事情就是创建并初始化Lua虚拟机。
1. 创建Lua虚拟机 lua_State *lua_newstate(lua_Alloc f, void *ud) API可以为我们创建一个新的独立的Lua虚拟机。 参数指定了虚拟机中的内存分配策略,例如我们已经在自己的代码中实现了内存池,这时候只需要写一个符合lua_Alloc原型的适配器,然后指定为Lua的内存分配器就可以了,使得内存分配更加灵活。当然,如果不想自定义内存分配策略,也可以使用luaL_newstate,这样Lua会帮你定义默认的内存分配策略。 我们可以先来看一下luaL_newstate的源码:
可见,通过luaL_newstate 创建Lua虚拟机时,第一块申请的内存将用来存储global_State(全局状态机)和lua_State(主线程)实例。为了避免内存碎片的产生,同时减少内存分配和释放的次数,Lua采用了一个小技巧:利用一个LG结构,把分配lua_State和global_State的行为关联在一起。这个LG结构是在C文件内部定义,而不存在公开的H文件中,仅供该C代码文件使用,因此这种依赖数据结构内存布局的用法负作用不大。
2. 关于global_State和lua_State 在一个独立的Lua虚拟机中,global_State是一个全局的结构, 而lua_State可以有多个。
global_State global_State结构,我们可以称之为Lua全局状态机。从Lua的使用者角度来看,global_State结构是完全感知不到的:我们无法用Lua公开的API获取到它的指针、句柄或引用,而且实际上我们也并不需要引用到它。但是对于Lua的实现来说,global_State是十分重要的部分。 它管理着Lua中全局唯一的信息,主要是以下功能:
(1)内存分配策略及其参数
在调用lua_newstate的时候配置它们. 也可以通过lua_getallocf和lua_setallocf随时获取和修改它
(2)字符串的hashtable
全局的字符串哈希表,即保存那些短字符串,使得整个虚拟机中短字符串只有一份实例。具体参见 Lua字符串处理
(3)垃圾回收相关的信息,内存使用统计量
(4)panic, 当无保护调用发生时, 会调用该函数, 默认是null, 可以通过lua_atpanic配置.(用于异常处理)
(6)记录lua中元方法名称 和 基本类型的元表
[注意, lua中table和userdata每个实例可以拥有自己的独特的元表--记录在table和userdata的mt字段, 其他类型是每个类型共享一个元表--就是记录在这里].
(7)upvalue链表
(8)主lua_State, 一个lua虚拟机中, 可以有多个lua_State, lua_newstate会创建出一个lua_State(称为主线程), 并邦定到global_state的主lua_State上
lua_State
线程,这里线程的概念区别于操作系统的线程,实际上也是Lua中定义的一种状态机。lua_State主要是管理一个lua虚拟机的执行环境, 一个lua虚拟机可以有多个执行环境。
(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的通信.
3. lua_newstate函数的流程 (1)新建一个global_state和一个lua_State (2)初始化, 包括给g_s创建注册表, g_s中各个类型的元表的默认值全部置为0 (3)给l_s创建全局表, 预分配l_s的CallInfo和stack空间
(4)其中涉及到了内存分配统统使用lua_newstate传进来的内存分配器分配
OK,这篇文章主要是借lua_newstate讲述global_State和lua_State的结构与作用,希望对大家了解Lua工作环境有一点帮助。 下一篇将讲述Lua栈相关的内容,更新中。。。
参考文献:
http://www.cnblogs.com/ringofthec/archive/2010/11/09/lua_State.html http://blog.csdn.net/maximuszhou/article/details/46277695 |
请发表评论