lua table # 取长度问题

任何语言都不是完美无瑕的,在使用中都有各种问题,lua 也不例外。而 lua 使用中,绝对绕不开的一个问题就是 # 取 table 长度问题。

问题描述

先看下 # 的一些使用情况,希望引起你的困惑:

> t = {1,1,nil,1}
> #t
4
> t = {nil,nil,1,nil}
> #t
0
> t = {1,nil,nil,nil,nil,nil,nil,1}
> #t
8
> t[9] = 1
> #t
1
> t = {1,nil,nil,nil,nil,nil,nil,1,1}
> #t
9

当 table 有部分值为 nil 时,你很难清楚 # 取得的结果是什么。(如果你想知道 table 实际长度,只能遍历 table)
继续阅读lua table # 取长度问题

lua定位CPU100%问题

在开始这个话题前,说下我遇到的 skynet 进程 CPU100% 占用问题,查找 bug 的过程比较繁琐,后来想到做改进,这也是促成我写这篇文章的原因。

查到是一段 lua 代码有问题,这里截取其中出问题的代码:

-- 活动开始时间: 2033-01-01 00:00:00
local start_time = 1988121600

function start_activity()
    local now = os.time()
    local diff = now - start_time
    if diff < 0 then
        skynet.timeout((-diff)*100, start_activity)
        return
    end

    -- todo 省略活动内容
end

以上代码,通过 skynet.timeout 设置定时器,定时触发 start_activity , 看似没有问题,但是,当 skynet.timeout 第一个参数过大时,会有意想不到的收获。
继续阅读lua定位CPU100%问题

lua5.4 分代垃圾回收

前注

最近我看了 lua 5.4 分代垃圾回收的代码,网上很少讲到这块内容,于是,我写这篇文章分享一下,也当做总结。文章就以我看的 lua 5.4.4 做分析。

在进入今天的主题前,先回顾我之前写的 lua5.3 垃圾回收分析,重复的内容不再赘述。

lua 5.4 支持两种 gc 方式, 增量式 gc 和分代 gc ,默认是增量式,可以通过以下 api 切换。

切换成分代 gc:
collectgarbage "generational"
切换成增量式 gc:
collectgarbage "incremental"

提出问题

1. 增量式 gc 跟分代 gc 的对比?
2. 分代 gc 过程是怎样的?
3. 分代 gc 有哪些状态?
4. 分代 gc 怎么调优?

继续阅读lua5.4 分代垃圾回收

找到 lua 死循环代码

最近遇到 lua 死循环的情况,就研究下如何找到死循环所在的代码,方便定位和解决问题。

首先,要找到出问题的协程(lua_State)。lua vm 实现时,每个协程都有自己独立的堆栈(stack),以及函数栈(CallInfo)。

所以,要先找到死循环的协程,再从这个协程函数栈找到代码。

怎么找到这个协程?

有三种办法:
方法1、 在死循环会执行到的 opcode ,加代码取得当前协程;
方法2、 遍历所有 gc 数据对象,找到当前正在执行的协程;
方法3、 重写 coroutine.resume 及 wrap 函数,取得当前协程。
继续阅读找到 lua 死循环代码

lua 开发防坑指南

原文 2015-09-27 10:47:28 发表于 CSDN,这里对以前写的文章做下收录。

Lua可以被C/C++ 代码调用,反过来也可以调用C/C++的函数,这使得Lua被广泛应用。Lua由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以运行。文章列举lua使用中遇到的坑点,做个汇总。

if判断

lua把 nil 和false 视为“假”,其他都为“真”

逻辑运算符 and or

lua的and or 可以用来构成三元表达式,如下:

> = 1 == 1 and 1 or 2
1

但如果是这样写,就不是你想要的结果了:

> = 1 == 1 and false or true
true

这是因为,and 运算符判定 false不成立,就继续执行了 or 运算符的结果
如果你一定要返回 true 或 false,要这么写:

> = ( 1 == 1 and {false} or {true} )[1]
false

继续阅读lua 开发防坑指南