Lua使用心得(2)

在lua脚本调用中,如果我们碰到一种不好的脚本,例如:while1dodoend那我们的程序主线程也会被阻塞住。那我们如何防止这种问题呢?下面就给出一个解决的办法。首先为了不阻塞主线程,

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

在lua脚本调用中,如果我们碰到一种不好的脚本,例如:

 

while 1 do

     do

end

 

那我们的程序主线程也会被阻塞住。那我们如何防止这种问题呢?下面就给出一个解决的办法。

 

首先为了不阻塞主线程,那我们就要开一个线程,把处理脚本的操作都放在这个新开的工作线程里。(要详细了解工作线程和界面线程的区别和管理,请参看本人的另一篇文章BLOG下Windows编程里的《Windows 线程漫谈——界面线程和工作者线程》)。

 

总体思路:

1、开线程来执行脚本解析,下面是StartRun()

2、导出一个判断是否结束函数,让脚本每个循环都调用,判断线程是否该结束了,这个函数在下面是IsThreadExit(),返回一个字符串(”exit” 表示while循环该结束了,”Notexit” 表示线程还不能结束)

3、如果主线程需要主动结束线程,就调用StopRun()

4、最好导出一个 ySleep 停顿函数,以免while循环里执行太快,导致CPU被高占用。http://hovertree.com/

 

 

按照这种思路,lua脚本变成如下形式:

while 1 do
 

    exitThread=IsThreadExit();
    ySleep(100);

    if exitThread == “exit” then
        break;
    end;

end;

 

VC代码如下,其中的Output是一个输出函数,你可以用MessageBox来代替:

 

// 全局变量

 

// 标志线程是否要结束
BOOL g_bExitDofile = FALSE;
// 线程句柄
HANDLE g_hDofile = NULL;

 

 

// 需要导出的函数

 

// 让 Lua 判断循环是否可以退出
static int IsThreadExit(lua_State* L)
{
 if(g_bExitDofile)
  lua_pushlstring(L, “exit”, 4);
 else
  lua_pushlstring(L, “Notexit”, 7);
 
 // 一个返回值
 return 1;
}

 

// 停顿函数

int ySleep(lua_State* L)
{
 int d = luaL_checkinteger(L, 1);
 Sleep(d);
 
 return 0;
}

 

// 注册以上函数

int RegFunc()

{
        lua_pushcfunction(g_pLua, IsThreadExit);
        lua_setglobal(g_pLua, “IsThreadExit”);
 
        lua_pushcfunction(g_pLua, ySleep);
        lua_setglobal(g_pLua, “ySleep”);

 

        return 0;

}

 

 

// 线程函数

DWORD WINAPI DofileThread(LPVOID lpParam)
{
  LPCTSTR strFilePath = (LPCTSTR)lpParam;
 luaL_dofile(g_pLua, strFilePath);
  
 StackDump(g_pLua);
 
 return 0;
}

 

// 线程启动

int StartRun(LPCTSTR strFilePath)
{

 // 注册所有需要导出的函数
 RegFunc();

 if(g_hDofile == NULL)
 {
  // 创建线程来执行LUA脚本
  g_hDofile = CreateThread(NULL, 0, DofileThread, (LPVOID)strFilePath, 0, NULL);
 }
 else
 {
  Output(“请先调用StopRun()”);
 }

 return 0;
}

 

// 停止线程

int StopRun()
{
 // 如果线程正在跑
 if(g_hDofile)
 {
  // 给lua循环结束的信号
  g_bExitDofile = TRUE;
  // 等待线程退出
  DWORD dwRet = WaitForSingleObject(g_hDofile, INFINITE);
  
  // 如果顺利退出
  if(dwRet == WAIT_OBJECT_0)
  {
   CloseHandle(g_hDofile);
   g_hDofile = NULL;
   g_bExitDofile = FALSE;
   
   Output(“Dofile thread exited!”);
  }
  // 否则强硬杀掉线程
  else
  {
   DWORD dwExitCode; 
   GetExitCodeThread(g_hDofile, &dwExitCode);

   TerminateThread(g_hDofile, dwExitCode);

   g_hDofile = NULL;
   g_bExitDofile = FALSE;
   
   Output(“Dofile thread was killed!”);
  }
 }

 return 0;
}

 

上面这个方法是利用了线程的本身特性解决掉脚本阻塞的问题。还可以使用LUA本身的HOOKS机制来防止脚本的阻塞,这个方法下次再说了。。。

http://www.cnblogs.com/roucheng/p/suanfa4.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/120442.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • C语言面试题汇总(持续更)「建议收藏」

    C语言面试题汇总(持续更)「建议收藏」笔者最近在找工作,因此对应聘C/C++嵌入式开发工程师容易被问到,或者经常搞不清楚的问题做一个汇总,也希望能对找工作的小伙伴起到帮助参考的作用。本篇集中于C语言方面的面试题目。因为是自己总结的,可能会存在错误,还烦请各位读者批评指正。一、变量内存分配1.一个由C/C++编译的程序占用的内存分为以下几个部分:①栈区——局部变量——向低地址生长——自动释放——其操作方式类似于数据结构中的栈。②堆区——向高地址生长——手动分配、释放的存储区——malloc,fr..

  • Windows系统重装Linux系统

    Windows系统重装Linux系统PC机以前是Windows系统现在重装Linux系统材料:8G以上U盘(eveything版本很大,如果U盘容量不足请选择DVD版本ISO)UltralSOLinux系统(Centos7_64_eveything.iso)tips:准…

  • 维度建模方法论[通俗易懂]

    维度建模方法论[通俗易懂]维度建模方法一、前言本人学习《数仓工具箱》的学习总结,纯学习分享,供大家参考。二、经典数仓架构理论围绕着维度建模,那就不得不了解,早期的数据仓库构架方法。这里介绍一下两个经典的数仓架构理论。2.1、Kimball模式Kimball模式从流程上看是是自顶向下的,即从数据集市到数据仓库再到数据源(先有数据集市再有数据仓库)的一种敏捷开发方法。对于Kimball模式,数据源每每是给定的若干个数据库表,数据较为稳定但是数据之间的关联关系比较复杂,须要从这些OLTP中产生的事务型数据结构抽取出分析型

  • AVC1与H264的差别

    AVC1与H264的差别

    2021年11月30日
  • pycharm无法安装第三方模块_如何在pycharm中安装第三方库

    pycharm无法安装第三方模块_如何在pycharm中安装第三方库使用pytharm安装python的第三方库很方便,但常常也会报错,下面归纳一些常见的问题。1.pip版本太老这应该是最常见的问题了,解决办法就是更新pip版本,升级命令如下:python-mpipinstall–upgradepip查看pip版本命令如下:pip-V2.更换源镜像pycharm默认的安装源网址是https://pypi.python….

  • 怎么把sql删干净_sql的导入和导出的好处

    怎么把sql删干净_sql的导入和导出的好处程序数据库(PDB)文件保存着调试和项目状态信息,使用这些信息可以对程序的调试配置进行增量链接。在使用/debug生成时,会创建一个PDB文件。可以使用/debug:full或/debug:pdbonly生成应用程序。使用/debug:full生成将产生可调试的代码。使用/debug:pdbonly生成将产生PDB,但是不会产生通知JIT编译器调试信息可用…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号