0
点赞
收藏
分享

微信扫一扫

Lua中文语言编程源码-第五节,更改lcorolib.c协程库函数, 使Lua加载中文库关键词(与所有的基础库相关)

源码已经更新在CSDN的码库里:

git clone https://gitcode.com/funsion/CLua.git

在src文件夹下的lcorolib.c协程库函数,Coroutine Library:表明这个C源文件实现了Lua的协程库(Coroutine Library),即提供了与协程相关的API和功能实现。

增加中文版协程函数名列表,保留英文版协程函数名列表。

原始的代码为:
static const luaL_Reg co_funcs[] = {
  {"create", luaB_cocreate},
  {"resume", luaB_coresume},
  {"running", luaB_corunning},
  {"status", luaB_costatus},
  {"wrap", luaB_cowrap},
  {"yield", luaB_yield},
  {"isyieldable", luaB_yieldable},
  {"close", luaB_close},
  {NULL, NULL}
};
 更改成以下代码:

/*
 * 协程功能的注册表
 * 该表包含了所有协程相关函数的英文名和中文名,以及它们对应的实现函数。
 * 该注册表用于在Lua中注册这些协程函数,以便于在Lua脚本中调用。
 */

static const luaL_Reg co_funcs[] = {
   /* 英文版协程函数名 */
   {"create", luaB_cocreate}, /* 创建一个新的协程 */
   {"resume", luaB_coresume}, /* 恢复一个协程的执行 */
   {"running", luaB_corunning}, /* 获取当前正在运行的协程 */
   {"status", luaB_costatus}, /* 获取一个协程的状态 */
   {"wrap", luaB_cowrap}, /* 将一个函数封装成一个协程 */
   {"yield", luaB_yield}, /* 使当前协程挂起 */
   {"isyieldable", luaB_yieldable}, /* 检查当前协程是否可以挂起 */
   {"close", luaB_close}, /* 关闭一个协程 */

   /* 中文版协程函数名 */
   {"创建", luaB_cocreate}, /* 创建一个新的协程 */
   {"恢复", luaB_coresume}, /* 恢复一个协程的执行 */
   {"程名", luaB_corunning}, /* 获取当前正在运行的协程 */
   {"状态", luaB_costatus}, /* 获取一个协程的状态 */
   {"程包", luaB_cowrap}, /* 将一个函数封装成一个协程 */
   {"挂起", luaB_yield}, /* 使当前协程挂起 */
   {"可挂起", luaB_yieldable}, /* 检查当前协程是否可以挂起 */
   {"关闭", luaB_close}, /* 关闭一个协程 */

   {NULL, NULL} /* 注册表结束标志 */
};

为了保证中英文协程函数都可以加载,以便你可以复制英文原码来进行更改。所以保留了英文版协程函数名列表,这样就能使用两种文的函数。

{"create", luaB_cocreate}, /* 创建一个新的协程 */

 {"创建", luaB_cocreate}, /* 创建一个新的协程 */

其实它们都是加载同样的库名,算是加载了2次,以Lua内部算法,应该只会加载一次。

更改完之后,同样需要重新编译Lua的源码,实现以上列出的关键词的中文化。

注意,在Window系统下编译Lua, 最好将所有Lua的源码,重新保存成ANSI格式的文件,刚下载的默认的源码会是UTF-8格式的。

这个事情说三遍,

1,不然就会出现,Window下的UTF-8源码可编译,但Shell里的中文输出会乱码。
2,要不然就是Window的ANSI源码不可编译(假如你没做以上步骤),
3,如果是用ANSI格式的源码编译的Lua.exe,对应的,你在Window下写的Lua程序也是需要保存成ANSI格式的。这样就可以在Shell里输出正确的中文显示。

这里就上例程演示,协程中文使用。

第一个协程 = 协程.创建(
    函数(i)
        输出(i,"协程.程名",协程.程名()) 
    结束
)
 
协程.恢复(第一个协程, "第一个协程运作")              -- 第一个协程运作  协程.程名       thread: 000001ba09d9a458        false
输出(i,"协程.状态", 协程.状态(第一个协程))           --i是传导不出来的,所以是nil, 协程.状态是(第一个协程)
输出("协程.程名是主线程么1?", 协程.程名())           -- 应该是的运行后对比   thread: 000001ba09d95ee8        true

 
输出("--------------第一协程分界线------------------")
 
程序封装的协程 = 协程.程包(
    函数(i)
    输出(i,"协程.程名",协程.程名())                   --程序封装第一次查协程.程名       thread: 00000268b6735628        false
    结束
)
 
程序封装的协程("程序封装第一次")
--程序封装的协程(2)
输出("第一个协程.状态", 协程.状态(第一个协程))         -- 第一个协程.状态 废弃dead
输出("协程.程名是主线程么2?", 协程.程名())             -- 应该是的运行后对比   thread: 000001ba09d95ee8        true

输出("--------------第二协程分界线------------------")

-- 创建一个能迭代打印1到10的协程,同时在迭代到3时检查自身状态和当前运行的协程。
第二个协程 = 协程.创建(
    函数()
        因为 i=1,10 做
            输出("第二个协程第",i,"执行")                                   -- 打印协程第二个协程的执行次数。
            如果 i == 3 即

                输出("协程内查1次第二个协程.状态", 协程.状态(第二个协程))   -- 打印协程第二个协程的状态,在此处第二个协程为程名
                输出("有没有在第二协程内?")                                -- 此时还在的。
                输出("第二个协程.程名", 协程.程名())                        -- 打印当前正在运行的协程,为第二个协程的线程ID
                输出("协程内查2次第二个协程.状态", 协程.状态(第二个协程))    -- 打印协程第二个协程的状态,在此处第二个协程为程名
                输出("第二个协程.程名", 协程.程名())                        -- 打印当前正在运行的协程,为第二个协程的线程ID
                输出("其它协程.状态", 协程.状态())                          -- 打印其它协程的状态,在此处为nil空程名,已经跳出了第二个协程,此处直接为不输出了
                输出("其它协程.程名", 协程.程名())                          -- 打印其它协程的程名,已经跳出了第二个协程,此处直接为不输出了
                输出("第二个协程1.状态", 协程.状态(第二个协程))             -- 打印协程第二个协程的状态,因为被查其他协程状态后,已经跳出了第二个协程,此处直接为不输出了
                输出("有没有在第二协程内?")                                --已经跳出了第二个协程,此处直接为不输出了                
            结束
            协程.挂起()                                                     -- 暂停协程执行,让出CPU时间
        结束
    结束
)

-- 分三次恢复协程第二个协程的执行,使其分别打印1到3。
协程.恢复(第二个协程) --1
协程.恢复(第二个协程) --2
协程.恢复(第二个协程) --3

-- 打印协程第二个协程的状态和当前运行的协程状态。
输出("------------分界线回主线程了------------")

输出("主线程查第二个协程.状态", 协程.状态(第二个协程))                      -- 挂起suspended,因为协程在 因为 循环中挂起yield了
输出("协程.程名是主程么3?", 协程.程名())                             --应该是的运行后对比   thread: 000001ba09d95ee8        true 
--输出("第二个协程.关闭", 协程.关闭(第二个协程))                     -- 如果已经不需要第二个协程再次运作,可以关闭协程。但这会导致协程代码里,之前在第二个协程内还有四行其它协程查询出错。
输出("协程.状态是主程么4?", 协程.状态(协程.程名()))                  --对上与第二个协程内的协程.状态() 留空查询时不同,此时应该是主线在运行。

输出("-----结束分界线-----")
-- 以上代码展示了协程的创建、恢复执行、状态查询以及yield的使用方法。

应该能吃透协程,入门了吧,如果还不行,请关注我,后面会放出专门针对协程的更详细的说明。

举报

相关推荐

0 条评论