GC竞争问题

在阅读Lua GC源码中,我们就提到过一个细节,所有带有__gc函数的对象,在第一轮GC循环中只会执行__gc函数,直到第二轮GC才真正清除。 一直没有找到必须这样做的场景,直到最近我发生了一例GC竞争的bug之后,才恍然大悟。回过头想想,其实在我之前翻译Barry Hayes大神的一篇论文里也早都提到过,只不过当时例子是释放OS资源,而场景也太过抽象,才没有引起我的注意。下面来看一个MWE。 我已经尽可能的精简代码,然而还是需要170+LOC。 在这个例子里,实现了一个链表管理,所有的link……

又一个lua调试器

最初,我并没有打算为Silly提供一个lua调试器,因为我本人不是一个重度调试器使用者。在开发期间出bug,看一下代码,打几条log可能比使用调试器会更快的找到问题,尤其是服务端程序,在很多时候其实只有log这一原始工具可以使用。但就我周围的人来推断,应该还是有很多重度调试器使用者。 因此,最终还是计划为Silly增加一个lua调试器作为基本组件存在。但是这个调试器到底以哪种方式提供调试功能,我一直在纠结中。 就我个人而言,我用过至少两种完全不同的调试器,gdb和dtrace(严……

给silly增加热更新

最新抽了点时间给silly增加了一个silly.patch模块,用于对热更新提供一些有限的支持。 热更新最麻烦之处莫过于“数据迁移”, 即怎么使新函数(要更新的函数)以“运行时数据”的状态运行。 其实http这类无状态协议是最为简单的,因为他们不需要“数据迁移”的过程。http的这种架构,使得所有的函数都是无副作用的,所有的数据在请求结束给出Response的同时, 数据就已经存入了数据库。当需要热更新函数时,根本就不需要考虑数据的问题,直接替换就可以完美解决。 与此相对的是,通常的服务……

实现了一个lualint

在使用动态语言的过程中,由于其运行时检查特性,很多手误并不能在刚运行时暴露出来。虽然并不会导致程序个程序crash掉,但总归是很麻烦的。 网上找了一个lualint试了试,效果还不错。这个工具的原理就是基于在写lua代码时并不会使用全局变量。在检测到全局变量时直接报警即可。 仔细研究了一下这个lualint的原理。 lua自带的工具luac是可以把编译后的OPCODE打印出来的,更关键的是自带注释。 利用OPCODE和注释就可以分析出在哪一行哪些变量是使用了什么全局变量。只要我们在代码中……

使用lua过程中需要注意事项

最近一段时间写了不少lua代码,由于这一次的代码量比以往都多,因此也就遇到了以前没有遇到问题, 需要说明的是,这就是一篇lua问题大集合, 并不涉及其他。 先说说遇到的问题及解决方案。 在lua中没有多余的数据结构,全靠一张表,这也是他简洁的根本所在。 当索引为全为数字时即可当数组使用,然而需要注意的是lua假设数组的索引一定是连续的,在此基础上lua尽可能快的优化了取数据长度的算法,因此lua对‘#’操作符的描述是“当table[i]不为nil, 而table[i+1]为nil时,则数组的长度为i……

lua gc的使用

主流的垃圾回收一般都是基于引用计数和标记清除算法. 从内存占用量上来讲, 引用计数无疑是有优势的, 当引用计数为0时, 直接就会将相应的对象清除, 典型的应用就是C++的智能指针. 但是基于引用计数的gc有一个坏处, 它无法解决循环引用问题. 如果A引用B会导致B的引用计数+1, B引用A也会导致A的引用计数+1, 这样A,B对象永远也不会删除. 记得在OC中似乎使用了弱引用来解决这个问题, 但总感觉这样会给代码中埋下坑. 标记清楚算法可以完美的解决循环引用问题, 其做法是从root遍历所有可达……

lua的debug_hook接口应用

lua本身并没有提供调试器, 但是提供了一组称为debug_hook的API, 这组API可以用来编写自己的调试器或者一些其他的东西。 这两天的工作主要就是研究了一下debug_hook这组接口, 写了一个极简化的lua调试器和一个lua性能分析器. lua调试器现在仅支持break point, step, print, coutinue这几个功能。 由于最近写lua已经习惯于不用调试器了, 因为实现的比较简单。 下断点时, 将要断点所在的文件与行号存入表中。 在不考虑效率的前提下, 直接用line mode来hook中每一行的运行,然后……

实现多国语言

大概一般的软件设计都需要至少支持两种以上的语言, 但是上一个软件中的多国语言设计一直是我心中的遗憾。今天刚看好看完“3D数学基础”, 学DX又提不起太大致, 于是决定重新写一个多国语言的demo也算弥补了上次的遗憾。 因为第一次设计多国语言的实现, 在设计中踩了许多坑,甚至于后来只能去切换主UI上的所有按钮的字符, 而所有对话框的UI则永远都英文状态。 除了鸡肋我实在想不到更能形象说明这个功能的形容词了。 设计之初的功能定义是可以让程序在运行过程中自由切换多国……

lua编码风格

最近都是在看lua代码, 并在其基础上进行修改和增加功能. 在代码中看到了不少个人感觉很不好的现象, 就忍不住吐槽一下. lua做为一门动态语言, 其弱类型及灵活性, 的确大大加快了开发和修改的效率. 但是这种自由有时不加以限制的使用, 有时候可能会造成很严重的后果. 先以我有限的理解说一下lua语言对于访问控制的有限支持. 定义变量或函数只有加上local才代表局部变量或函数, 否则只要这个模块被加载就可以被其他模块访问. require代表要去加载某个模块, 如果两次调用require去调……

lua_tothread的使用场景

在学习lua虚拟机与C交互过程中, 看到一个很令人奇怪的API, lua_tothread. lua官方手册上只是说明lua_tothread的作用是将一个thread(coroutine)以lua_State的形式表示出来, 但是总是搞不清这个API应该在什么情况下使用. 在做了一些实验后, 终于有点结论了. 在调用luaL_newstate函数去创建一个lua虚拟机时, lua就会自动在这个状态中创建一个新thread(coroutine), 这个线程被称为主线程. 除了调用lua_close之外, 这个主线程永远不会被回收. 在lua中每个coroutine都有一个lua_State与之……