Lua使用心得(2)
在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
Lua使用心得(2)的更多相关文章
- <转> Lua使用心得(2)
在lua脚本调用中,如果我们碰到一种不好的脚本,例如: do do end 那我们的程序主线程也会被阻塞住.那我们如何防止这种问题呢?下面就给出一个解决的办法. 首先为了不阻塞主线程,那我们就要开一个 ...
- Lua使用心得(1)
这几天研究了一下lua,主要关注的是lua和vc之间的整合,把代码都写好放在VC宿主程序里,然后在lua里调用宿主程序的这些代码(或者叫接口.组件,随便你怎么叫),希望能用脚本来控制主程序的行为.这实 ...
- (转) Lua使用心得一 LUA和VC整合
这几天研究了一下lua,主要关注的是lua和vc之间的整合,把代码都写好放在VC宿主程序里,然后在lua里调用宿主程序的这些代码(或者叫接口.组件,随便你怎么叫),希望能用脚本来控制主程序的行为.这实 ...
- JS在与lua的交互心得
最近在写一个项目,前端技术使用的是Vue,在与lua的交互过程,是通过一个公共JS,前端调用公共js的方法给lua发送命令,lua接到命令,去执行一些方法,然后又通过回调返回到了前端,由于是第一次写这 ...
- lua学习项目笔记
这几天草草的浏览了一下电子版的<lua程序设计>,没有懂的地方就自动忽略了,挑拣了一些可以理解的部分一直在推进.推进至后面的时候已经浑浑噩噩的了,有种想看完这本书的强迫症的感觉.推进CAP ...
- C++与Lua交互(一)
引言 之前做手游项目时,客户端用lua做脚本,基本所有游戏逻辑都用它完成,玩起来有点不爽,感觉"太重"了.而我又比较偏服务端这边(仅有C++),所以热情不高.最近,加入了一个端游项 ...
- 我的2016年终总结(PF项目框架设计心得分享 2.0rc)
在无数的日夜里,熬出了多少的黑眼圈,致勤勤恳恳工作的各位朋友与自己.每到了年末的时候总想写的什么,主要是为了回顾以往一年里到底做了什么,这便是年终总结的主要意义.在此我将要总结的是和我在技术层面上成长 ...
- lua 函数调用1 -- 闭包详解和C调用
这里, 简单的记录一下lua中闭包的知识和C闭包调用 前提知识: 在lua api小记2中已经分析了lua中值的结构, 是一个 TValue{value, tt}组合, 如果有疑问, 可以去看一下 一 ...
- tolua++实现lua层调用c++技术分析
tolua++技术分析 cocos2dx+lua 前言 一直都使用 cocos2dx + lua 进行游戏开发,用 Lua 开发可以专注于游戏逻辑的实现,另外一方面可以实现热更新:而且 lua 是一个 ...
随机推荐
- [ZigBee] 6、ZigBee基础实验——定时器3和定时器4(8 位定时器)
上一节讲了16位定时器1,本节讲8位定时器3和定时器4! 1.综述 Timer 3 and Timer 4 are two 8-bit timers(8位定时器). Each timer has tw ...
- [我给Unity官方视频教程做中文字幕]beginner Graphics – Lessons系列之纹理Textures
[我给Unity官方视频教程做中文字幕]beginner Graphics – Lessons系列之纹理Textures 本篇分享一下第6个已完工的视频,即<beginner Graphics ...
- Linux用户切换
1,查看当前user: whoami 2,普通用户切换到root,会要求输入密码: su 3,root切换到普通用户: su - username
- IOS 基础-define、const、extern、全局变量
这里介绍一下define.const.extern的用法.优劣以及要注意的地方. 1.define 宏define是定义一个变量,没有类型信息.define定义的常量在内存中有若干个拷贝. defin ...
- [Java面试四]Strust2总结及在面试中的一些问题.
1. JavaEE软件三层结构和MVC的区别? JavaEE软件三层机构是由sun公司提供JavaEE开发规范的:Web层(表现层).业务逻辑层.数据持久层.[其中WEB层会使用前端控制器模式] MV ...
- Atitit dsl对于数组的处理以及main函数的参数赋值
Atitit dsl对于数组的处理以及main函数的参数赋值 1.1. 词法解析..添加了[] 方括号的解析支持1 1.2. Ast建立.添加了数组参数的支持..使用了递归下降法..getparam ...
- c#设计模式-命令模式
一. 命令(Command)模式 命令(Command)模式属于对象的行为模式[GOF95].命令模式又称为行动(Action)模式或交易(Transaction)模式.命令模式把一个请求或者操作封装 ...
- Mina、Netty、Twisted一起学(五):整合protobuf
protobuf是谷歌的Protocol Buffers的简称,用于结构化数据和字节码之间互相转换(序列化.反序列化),一般应用于网络传输,可支持多种编程语言. protobuf如何使用这里不再介绍, ...
- C#调用Couchbase中的Memcached缓存
安装服务端 服务端下载地址:http://www.couchbase.com/download 选择适合自己的进行下载安装就可以了,我这里选择的是Win7 64. 服务端安装完后,如果成功了,那么在浏 ...
- 使用SQL Server作业设置定时任务
1.开启SQL Server Agent服务 使用作业需要SQL Agent服务的支持,并且需要设置为自动启动,否则你的作业不会被执行. 以下步骤开启服务:开始-->>>运行--&g ...