【Lua进阶系列】全局状态机global_State
大家好,我是Lampard~~
欢迎来到Lua进阶系列的博客
前文再续,书接上一回。今天和大家讲解一下lua中的全局状态机global_State。
(一)什么是全局状态机global_State
global_State 里面有对主线程的引用,有注册表管理所有全局数据,有全局字符串表,有内存管理函数,有GC 需要的把所有对象串联起来的相关信息,以及一切 lua 在工作时需要的工作内存。
(二)全局状态机global_State的组成
typedef struct global_State {
/* 版本号 */
const lua_Number *version; /* pointer to version number */
/* 内存管理 */
lua_Alloc frealloc; /* Lua的全局内存分配器,用户可以替换成自己的 - function to reallocate memory */
void *ud; /* 分配器的userdata - auxiliary data to 'frealloc' */
/* 线程管理 */
struct lua_State *mainthread; /* 主线程 */
struct lua_State *twups; /* 闭包了当前线程变量的其他线程列表 - list of threads with open upvalues */
/* 字符串管理 */
stringtable strt; /* 字符串table Lua的字符串分短字符串和长字符串 - hash table for strings */
TString *strcache[STRCACHE_N][STRCACHE_M]; /* 字符串缓存 - cache for strings in API */
/* 虚函数表 */
TString *tmname[TM_N]; /* 预定义方法名字数组 - array with tag-method names */
struct Table *mt[LUA_NUMTAGS]; /* 每个基本类型一个metatable(整个Lua最重要的Hook机制) - metatables for basic types */
/* 错误处理 */
lua_CFunction panic; /* to be called in unprotected errors */
TString *memerrmsg; /* memory-error message */
/* GC管理 */
unsigned int gcfinnum; /* number of finalizers to call in each GC step */
int gcpause; /* size of pause between successive GCs */
int gcstepmul; /* GC 'granularity' */
l_mem totalbytes; /* number of bytes currently allocated - GCdebt */
l_mem GCdebt; /* bytes allocated not yet compensated by the collector */
lu_mem GCmemtrav; /* memory traversed by the GC */
lu_mem GCestimate; /* an estimate of the non-garbage memory in use */
TValue l_registry;
unsigned int seed; /* randomized seed for hashes */
lu_byte currentwhite;
lu_byte gcstate; /* state of garbage collector */
lu_byte gckind; /* kind of GC running */
lu_byte gcrunning; /* true if GC is running */
GCObject *allgc; /* list of all collectable objects */
GCObject **sweepgc; /* current position of sweep in list */
GCObject *finobj; /* list of collectable objects with finalizers */
GCObject *gray; /* list of gray objects */
GCObject *grayagain; /* list of objects to be traversed atomically */
GCObject *weak; /* list of tables with weak values */
GCObject *ephemeron; /* list of ephemeron tables (weak keys) */
GCObject *allweak; /* list of all-weak tables */
GCObject *tobefnz; /* list of userdata to be GC */
GCObject *fixedgc; /* list of objects not to be collected */
} global_State;
简单来说,全局状态机由一下几部分组成:
1. version : 版本号
2. panic : 全局错误处理
3. stringtable : 全局字符串表, 字符串池化,buff 在 字符串处理过程中的临时缓存区(编译过程中的parse也需要使用这块buff)。
4. l_registry : 注册表(管理全局数据)
5. seed : 字符串 Hash 随机化
6. Meta table :tmname (tag method name) 预定义了元方法名字数组;mt 每一个Lua 的基本数据类型都有一个元表。
7. Thread Info:mainthread 指向主线程(协程);twups 闭包了当前线程(协程)变量的其他线程列表。
8. Memory Allocator:frealloc 指向 Lua的全局内存分配器;ud 指向内存分配器的data。
9. GC 相关信息
(三)全局状态机global_State初始化过程
通过 lua_newstate 创建一个新的 lua 虚拟机时,第一块申请的内存将用来保存主线程和这个全局状态机,并初始化了global_State 中需要引用的数据。
g->mainthread = L; 同时将G 中的 L 指针指向刚分配的内存的lua_Stack ,到这里 L 与 G 互相持有
参考博客:
Lua 5.3 源码分析(三) 全局状态机global_State
OK,今天的博客就到这里,谢谢大家!!!