本文内容基于版本:Lua 5.3.0

global_State概述


global_State结构,我们可以称之为Lua全局状态机。从Lua的使用者角度来看,global_State结构是完全感知不到的:我们无法用Lua公开的API获取到它的指针、句柄或引用,而且实际上我们也并不需要引用到它。但是对于Lua的实现来说,global_State是十分重要的部分:它里面有对主线程(lua_State实例)的引用、有全局字符串表、有内存管理函数、有GC需要的相关信息以及一切Lua在工作时需要的工作内存等等。

global_State与lua_State结构的关联


通过luaL_newstate函数创建虚拟机时,第一块申请的内存将用来存储lua_State(主线程)和global_State(全局状态机)实例。为了避免内存碎片的产生,同时减少内存分配和释放的次数,Lua采用了一个小技巧:利用一个LG结构,把分配lua_Stateglobal_State的行为关联在一起。这个LG结构是在C文件内部定义,而不存在公开的H文件中,仅供该C代码文件使用,因此这种依赖数据结构内存布局的用法负作用不大。

// luaconf.h
/*
@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
** a Lua state with very fast access.
** CHANGE it if you need a different size.
*/
#define LUA_EXTRASPACE (sizeof(void *)) // lstate.c
/*
** thread state + extra space
*/
typedef struct LX {
lu_byte extra_[LUA_EXTRASPACE];
lua_State l;
} LX; /*
** Main thread combines a thread state and the global state
*/
typedef struct LG {
LX l;
global_State g;
} LG;

global_State的创建和销毁


• global_State的创建和初始化

// lstate.c
LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
int i;
lua_State *L;
global_State *g;
LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
if (l == NULL) return NULL;
L = &l->l.l;
g = &l->g;
......
return L;
}

• global_State的销毁

// lstate.c
LUA_API void lua_close (lua_State *L) {
L = G(L)->mainthread; /* only the main thread can be closed */
lua_lock(L);
close_state(L);
} // lstate.c
static void close_state (lua_State *L) {
global_State *g = G(L);
luaF_close(L, L->stack); /* close all upvalues for this thread */
luaC_freeallobjects(L); /* collect all objects */
if (g->version) /* closing a fully built state? */
luai_userstateclose(L);
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
luaZ_freebuffer(L, &g->buff);
freestack(L);
lua_assert(gettotalbytes(g) == sizeof(LG));
(*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
}

fromstate(L)宏


fromstate(L)宏的实现源码:

// stddef.h(Linux & Windows)
#define offsetof(s,m) (size_t)&(((s *)0)->m) // llimits.h
#define cast(t, exp) ((t)(exp)) // lstate.c
#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))

fromstate(L)宏的实现图解:

lua全局状态机的更多相关文章

  1. cocos2d-x lua 实现状态机

    cocos2d-x lua 实现状态机 version: cocos2d-x 3.6 0.状态机 状态机主要分为2大类:第一类,若输出只和状态有关而与输入无关,则称为Moore状态机:第二类,输出不仅 ...

  2. lua堆栈

    lua堆栈 来源 https://blog.csdn.net/suhuaiqiang_janlay/article/details/56702381 来源 https://blog.csdn.net/ ...

  3. Lua 5.1 参考手册

    Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes 云风 译 www.codingno ...

  4. 利用 Lua 实现 App 动态化方案

    因为动态化的东西我第一次看实现方案的源码,而且目前还是大三的学生,缺少很多实践经验说错的地方还请原谅,也希望能指出,被告知.想了很久还是决定写出来,求大神勿喷. 并且我的一个朋友bestswifter ...

  5. lua 源码分析之线程对象lua_State

    lua_State 中放的是 lua 虚拟机中的环境表.注册表.运行堆栈.虚拟机的上下文等数据. 从一个主线程(特指 lua 虚拟机中的线程,即 coroutine)中创建出来的新的 lua_Stat ...

  6. lua内存管理

    本文内容基于版本:Lua 5.3.0 Lua内存管理器规则 Lua允许用户自定义内存管理器,并在创建Lua虚拟机(lua_State实例)时传入.当然自定义内存管理器必须遵循Lua已定义的一些行为规则 ...

  7. lua字符串

    本文内容基于版本:Lua 5.3.0 概述 Lua字符串中的合法字符可以是任何的1字节数据,这包括了C语言中表示字符串结束的'\0'字符,也就是说Lua字符串在内部将以带长度的内存块的形式存储,存储的 ...

  8. Lua 常用函数 一

    lua_getallocf lua_Alloc lua_getallocf (lua_State *L, void **ud); 返回给定状态机的内存分配器函数.如果 ud 不是 NULL ,Lua ...

  9. c++调用lua

    我们主要解决如下几个问题: 转:http://www.cnblogs.com/zisou/p/cocos2dx-lua2.html http://www.cnblogs.com/sevenyuan/p ...

随机推荐

  1. C语言错误: CRT detected that the application wrote to memory after end of heap buffer

    CRT detected that the application wrote to memory after end of heap buffer 多是中间对其进行了一些操作,在程序结束处,释放内存 ...

  2. multimap 小例子

    场景: 按DDX值倒序取前十的板块代码,用 map<float, string, greater<float> > mapBKDDX; 存储时,相同DDX值的板块只能存储第一个 ...

  3. 5.3 SpEL语法

    SqEL是一个可以独立于spring的表达式语言,即它可以用在XML中对语法进行简化 5.3 SpEL语法5.3.1 基本表达式一.字面量表达式: SpEL支持的字面量包括:字符串.数字类型(int. ...

  4. Github+Jekyll —— 创建个人免费博客(五)jekyllproject公布到github上

    摘要: 本文中我将介绍一下怎样在github上搭建个人Blog(博客),也顺便让我们掌握一下github Pages功能,另外还涉及到Jekyll技术. ======================= ...

  5. web版pdf在线阅读器

    近期论坛里有人提到了,在线pdf阅读器怎么做.我百度了一下,发现非常多人都非常懒.程序猿都非常懒吗? 答案是否定的. 为什么都不愿意去搜索一下呢.网上非常多答案的.我这里就列举一例.大家共勉. 看代码 ...

  6. 实现 IteratorAggregate接口

    <?php class MyIterator implements Iterator{ private $var = array(); public function __construct($ ...

  7. SDL 威胁建模工具入门 threat modeling tool

    http://msdn.microsoft.com/zh-cn/magazine/dd347831.aspx threat modeling tool 威胁建模工具 minifuzz 文件模糊工具 c ...

  8. 苹果微信浏览器不能post方式提交数据问题

    form表单中采用post方式提交数据时,在苹果的微信浏览器中无法传递,安卓的可以 如图: 在controller中获取该数据为 null 将表单的提交方式修改为get就能够获取到 现在采用Ajax方 ...

  9. aiohttp笔记

    目录 简介 采集模板 一批,一次性采集 动态添加任务 动态添加任务,封装成类 简介 aiohttp需要python3.5.3以及更高的版本,它不但能做客户端爬虫,也能做服务器端,利用asyncio,协 ...

  10. angular2+ 中封装调用递归tree

    子组件  given-person.html <!--权限设置-选择员工--> <li [class.noborder]="!dir.shierarchy" *n ...