lua多线程

原创 2018年04月15日 13:54:37

lua5.3.4在Windows下多线程


作者:Mrzhu007
日期:2018-04-15
博客地址:金色世界


简介

之前做的一个测试项目。在使用lua脚本对一些固件测试的时候,需要lua满足多线程。来进行同步检测

实现

该方案由网友提供,在github上也可以下载。在使用过程中,有一些bug已进行修改。适配与lua5.3.4版本.
以防以后忘掉,故整理成文档。各位网友喜欢的话不妨拿去使用。我只在测试项目中使用。
在使用多线程的时候请让线程自己终止,或者使用lua变量外界控制。
不要使用库中提供的终止线程函数。有问题,但不影响使用,就没改。

  • 第一步GitHub下载最新lua源码
  • 第二步添加一下.c文件名字自己取建议systhread。将下面的源码复制进去

    #include <Windows.h> 
    #include "lua.h"
    #include "lauxlib.h"
    #include "lualib.h"
    #include "lstate.h"
    
    #define TNAMESTR_SYSTHREAD "g_utype_systhread"// userdata type name
    
    typedef struct _SysThread
    {
        lua_State *thread;
        int        ref;//在C注册表中的引用,防止被回收
        DWORD      id;
        HANDLE     handle;
    }SysThread;
    
    DWORD WINAPI ThreadProc(LPVOID lp)
    {
        SysThread *st = (SysThread *)lp;
        int ntop = lua_gettop(st->thread);
        int err = lua_pcall(st->thread, ntop-1, 0, 0);
        if (err) printf("[Thread %x callback error] %s", st, lua_tostring(st->thread, -1));
        if (st->ref) luaL_unref(st->thread, LUA_REGISTRYINDEX, st->ref);
        return err;
    }
    
    static int luaB_newthread (lua_State *L);
    
    static int luaB_resumethread (lua_State *L) 
    {
        SysThread *st = (SysThread *)luaL_checkudata(L, 1, TNAMESTR_SYSTHREAD);
    
        int count = ResumeThread(st->handle);
        if (count == -1) 
            lua_pushboolean(L, 0);
        else
            lua_pushinteger(L, count);
        return 1;
    }
    
    static int luaB_suspendthread (lua_State *L) 
    {
        SysThread *st = (SysThread *)luaL_checkudata(L, 1, TNAMESTR_SYSTHREAD);
        int count = SuspendThread(st->handle);
        if (count == -1) 
            lua_pushboolean(L, 0);
        else 
            lua_pushinteger(L, count);
        return 1;
    }
    
    static int luaB_terminatethread(lua_State *L) 
    {   
        SysThread *st = (SysThread *)luaL_checkudata(L, 1, TNAMESTR_SYSTHREAD);
        BOOL b = TerminateThread(st->handle, lua_isnoneornil(L, 2) ? 0 : luaL_checkinteger(L, 2));
        lua_pushboolean(L, b);
        luaL_unref(st->thread, LUA_REGISTRYINDEX, st->ref);  st->ref = 0;
        return 1;
    }
    
    static int luaB_waitthread(lua_State *L) 
    {
        SysThread *st = (SysThread *)luaL_checkudata(L, 1, TNAMESTR_SYSTHREAD);
        WaitForSingleObject(st->handle,
        lua_isnoneornil(L, 2) ? INFINITE : luaL_checkinteger(L, 2));
        return 0;
    }
    
    static int luaB_getthreadexitcode(lua_State *L) 
    {
        SysThread *st = (SysThread *)luaL_checkudata(L, 1, TNAMESTR_SYSTHREAD);
    
        DWORD exitCode;
        BOOL b = GetExitCodeThread(st->handle, &exitCode);
        if (b)
            lua_pushinteger(L, exitCode);
        else if (exitCode == STILL_ACTIVE)
            lua_pushboolean(L, b);
        else
            lua_pushnil(L);
        return 1;
    }
    
    static int luaB_getid(lua_State *L) 
    {
        SysThread *st = (SysThread *)luaL_checkudata(L, 1, TNAMESTR_SYSTHREAD);
    
        lua_pushinteger(L, st->id);
        lua_pushinteger(L, (int)st->handle);
        return 2;
    }
    
    static int luaB_threadsleep(lua_State *L) 
    {
        Sleep(luaL_checkinteger(L, 1));
        return 0;
    }
    
    static const luaL_Reg systhreadlib[] = 
    {
        {"create",luaB_newthread},
        {"resume",luaB_resumethread},
        {"suspend",luaB_suspendthread},
        {"terminate",luaB_terminatethread},
        {"wait",luaB_waitthread},
        {"exitcode",luaB_getthreadexitcode},
        {"getid",luaB_getid},
        {"sleep",luaB_threadsleep},
        {NULL,NULL}
    };
    
    static int luaB_newthread (lua_State *L)
    {   
        int nTop;
        lua_State* newthr;
        int ref;
        SysThread *st;
        luaL_checktype(L, 1, LUA_TFUNCTION);
    
        nTop = lua_gettop(L);
        newthr = lua_newthread(L);
        ref = luaL_ref(L, LUA_REGISTRYINDEX);//放到C注册表中防止被回收
        lua_xmove(L, newthr, nTop);//把启动函数以及参数移到新的lua_State 中
    
        st = (SysThread *)lua_newuserdata(L, sizeof(SysThread));
        st->ref = ref;
        st->thread = newthr;
        //创建系统线程
            if ((st->handle = CreateThread(NULL, 0, ThreadProc, st, CREATE_SUSPENDED, &st->id)))
        {   
            luaL_newmetatable(L, TNAMESTR_SYSTHREAD); //创建一个类型为 TNAMESTR_SYSTHREAD 的userdata
            luaL_newlib(L,systhreadlib); //
            lua_setfield(L, -2, "__index");
            lua_setmetatable(L, -2);
        }
        else //创建失败,返回false
        if (!st->handle) { lua_pushboolean(L, 0); }
        return 1;
    }
    
    int luaopen_systhread(lua_State *L) 
    {
        luaL_newlib(L, systhreadlib);
        return 1;
    }
    
  • 第三步在linit.c文件中的loadedlibs结构中添加如下:

    {LUA_SYSTHREADLIBNAME, luaopen_systhread},
    
  • 第四步在lstate.h文件中在添加

    //在lua_newstate中TString *strcache[STRCACHE_N][STRCACHE_M];  /* cache for strings in API */后面添加
    CRITICAL_SECTION cri_sec;
    
  • 第五步在lstate.c文件中添加

    //在lua_newstate中g->gcstepmul = LUAI_GCMUL;后面
    InitializeCriticalSection(&g->cri_sec);
    
  • 第六步在lualib.h文件中添加

    #define LUA_SYSTHREADLIBNAME    "systhread"
    LUAMOD_API int (luaopen_systhread) (lua_State *L);
    
  • 第七步在lundump.c文件中LoadString函数前面添加

    #undef LoadString   //ADDED BY ZHUGAOLEI
    

最后

好了,到此为止可以开启自己的lua多线程之路了。至于怎么编译lua和怎么使用lua。网上教程很多。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zgl390963305/article/details/79948795

Lua语言实现简单的多线程模型

lua本身是不支持真正的多线程的,但是lua提供了相应的机制来实现多线程。lua执行在一个lua环境中内部叫lua_State。如果我们创建多个lua_State,并且创建一一对应的线程来启动它就基本...
  • john_crash
  • john_crash
  • 2015-10-29 14:33:52
  • 9530

Lua基础 coroutine —— Lua的多线程编程

Lua的coroutine 跟thread 的概念比较相似,但是也不完全相同。一个multi-thread的程序,可以同时有多个thread 在运行,但是一个multi-coroutines的程序,同...
  • wzzfeitian
  • wzzfeitian
  • 2013-04-29 14:22:46
  • 30994

lua中的线程详解

文章转自:http://www.cnblogs.com/zrtqsk/p/4374360.html 我们首先介绍一下什么是协程、然后详细介绍一下coroutine库,然后介绍一下协程的简单用法,...
  • gulan0
  • gulan0
  • 2015-12-21 17:23:32
  • 2276

Lua学习笔记-9.4章-非抢占式的多线程

1、coroutine运行一系列的协作多线程。每个coroutine相当于一个thread。通过yield-resume实现在不同thread之间切换控制权。但是,跟常规的multithr不同,cor...
  • ljp1919
  • ljp1919
  • 2016-04-07 17:38:00
  • 2699

【深入Lua】理解Lua中最强大的特性-coroutine(协程)

http://my.oschina.net/wangxuanyihaha/blog/186401 coroutine基础 Lua所支持的协程全称被称作协同式多线程(collabor...
  • sharemyfree
  • sharemyfree
  • 2015-08-12 11:42:42
  • 8441

Lua抢占式多线程的编写(windows7系统)

写了那么久的单线程程序大家一定认为Lua只能实现简单的单线程的程序,当然如果你只用lua的话只能是单线程运行,然而如果你要用多线程,就需要找一个运行平台来做,windows或者linux都可以,这里我...
  • xueyunf
  • xueyunf
  • 2012-08-14 18:57:17
  • 2406

lua多线程

lua5.3.4在Windows下多线程 作者:Mrzhu007 日期:2018-04-15 博客地址:金色世界 简介 之前做的一个测试项目。在使用lua脚本对一些固件测试的时候,需...
  • zgl390963305
  • zgl390963305
  • 2018-04-15 13:54:37
  • 13

C++多线程服务端 和 lua客户端(A)

#include "server0.h" #include "stdafx.h" #include  #include  #include  #include  #pragma comment...
  • guotong1988
  • guotong1988
  • 2013-05-18 20:35:20
  • 1523

cocos2d-x3.2 下使用多线程

其实在cocos2dx下使用多线程其实就是用C++去写,这里提供几个简单的例子: 1、...
  • qqMCY
  • qqMCY
  • 2014-07-01 22:45:10
  • 2425

多线程中的lua同步问题

多线程中的lua同步问题 http://www.cnblogs.com/ghost240/p/3526185.html 最近写paintsnow::start时出现了一个非常麻...
  • ljhjason
  • ljhjason
  • 2014-03-26 20:37:05
  • 5790
收藏助手
不良信息举报
您举报文章:lua多线程
举报原因:
原因补充:

(最多只允许输入30个字)