<转>多线程中的lua同步问题
转自 http://www.cnblogs.com/ghost240/p/3526185.html
最近写paintsnow::start时出现了一个非常麻烦的BUG,程序的Release版本大约每运行十几次就会有一次启动时崩溃(Debug版本还没崩溃过),崩溃点也不固定。经过简单分析之后,确定是线程同步的问题。于是便修改了线程通信的代码,并使用pthread_mutex_lock/unlock来防止冲突。重新编译后,崩溃频率有所减少。但是每运行约四十次,还是免不了崩溃一次,而且冷启动时崩溃概率更大。
在VC中的Release版本中设置Generate Debug Info后,重复多次运行程序,好不容易得到了几次崩溃记录。综合这几次的崩溃点,可以发现崩溃基本都发生在重分配内存(operator new())时,而且调用堆栈中还显示调用过程中有luaVM的参与。经过多日跟踪,终于发现问题所在,特作记录。
首先简单说一下paintsnow的组织结构。paintsnow::start主要是由两个线程并行执行的,其中一个负责构架、绘图、消息处理等,由底层核心paintsnow.lib提供,另一个执行lua脚本,由luaVM和一些Paintsnow API构成。由于两个线程有时候需要调用另一个线程所提供的功能,因此可能会出现两个线程冲突的问题。之前的代码仅仅是对脚本线程call核心线程时做过调用转接和加锁处理,但是实际上有时核心线程也会call脚本(通常出现在各种回调函数中)。
网上的资料说解决多线程调用同一个luaVM的有效方案是使用lua_newthread来创建一个脚本线程单元,然后用新创建的单元作为lua_State来call。这一招在通常情况下是非常管用的,因为它成功避免了lua栈上的冲突。painsnow以前的方案就是这样写的。可是问题就出在lua本身为了兼容标准,并不包含线程同步的处理函数,所谓的newthread只是逻辑上的thread而非操作系统概念的thread,因此这样调用luaVM依然存在着重入的风险,特别是在内存重分配时会产生意思不到的错误。
当然,对于lua这种设计得非常优雅的库,自然对多线程有过考虑。通过lua的源码可以看出,lua在每一个不可重入的函数中都用lua_lock创建了一个锁以保证同步。默认情况下,由于同步锁并不包含在标准库中,所以lua_lock实际只是一个空宏:(llmits.h中有定义)
#define lua_lock(L) ((void)0)
如果想要添加多线程支持,需要重写它和lua_unlock两个宏。这不是难事,以添加pthread提供锁功能为例:
在lstate.h中,对GlobalState结构新加一个成员:
pthread_mutex_t lock;
然后在lua_newstate中添加初始化代码:
pthread_mutex_init(&g->lock, NULL);
接着重定义lock/unlock宏(写在原定义前面即可):
#define lua_lock(L) pthread_mutex_lock(&(G(L)->lock));
#define lua_unlock(L) pthread_mutex_unlock(&(G(L)->lock));
最后在close_state函数的末尾添加两行:
static void close_state (lua_State *L) {
global_State *g = G(L);
luaF_close(L, L->stack); /* close all upvalues for this thread */
luaC_freeallobjects(L); /* collect all objects */
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
luaZ_freebuffer(L, &g->buff);
freestack(L);
lua_assert(gettotalbytes(g) == sizeof(LG));
pthread_mutex_unlock(&g->lock);
pthread_mutex_destroy(&g->lock);
(*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
}
vc++ lua线程同步代源码修改 见 http://www.cnblogs.com/zhangdongsheng/p/3679024.html
<转>多线程中的lua同步问题的更多相关文章
- 多线程中的lua同步问题
最近写paintsnow::start时出现了一个非常麻烦的BUG,程序的Release版本大约每运行十几次就会有一次启动时崩溃(Debug版本还没崩溃过),崩溃点也不固定.经过简单分析之后,确定是线 ...
- C# .net 多线程中集合数据同步
from:http://www.cnblogs.com/GavinCome/archive/2008/04/09/1145250.html C# .net 多线程中集合数据同步(转) 集合类通常不是线 ...
- java多线程中并发集合和同步集合有哪些?区别是什么?
java多线程中并发集合和同步集合有哪些? hashmap 是非同步的,故在多线程中是线程不安全的,不过也可以使用 同步类来进行包装: 包装类Collections.synchronizedMap() ...
- python 多线程中的同步锁 Lock Rlock Semaphore Event Conditio
摘要:在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lo ...
- 进程?线程?多线程?同步?异步?守护线程?非守护线程(用户线程)?线程的几种状态?多线程中的方法join()?
1.进程?线程?多线程? 进程就是正在运行的程序,他是线程的集合. 线程是正在独立运行的一条执行路径. 多线程是为了提高程序的执行效率.2.同步?异步? 同步: 单线程 异步: 多线程 3.守护线程? ...
- Java多线程中的竞争条件、锁以及同步的概念
竞争条件 1.竞争条件: 在java多线程中,当两个或以上的线程对同一个数据进行操作的时候,可能会产生“竞争条件”的现象.这种现象产生的根本原因是因为多个线程在对同一个数据进行操作,此时对该数据的操作 ...
- Redis中的原子操作(2)-redis中使用Lua脚本保证命令原子性
Redis 如何应对并发访问 使用 Lua 脚本 Redis 中如何使用 Lua 脚本 EVAL EVALSHA SCRIPT 命令 SCRIPT LOAD SCRIPT EXISTS SCRIPT ...
- .NET面试题解析(07)-多线程编程与线程同步
系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实是很多的,比如多线程编程.线程上下文.异步编程.线程同步构造.GUI的跨线程访问等等, ...
- c#初学-多线程中lock用法的经典实例
本文转载自:http://www.cnblogs.com/promise-7/articles/2354077.html 一.Lock定义 lock 关键字可以用来确保代码块完成运行,而不会被 ...
随机推荐
- python 机器学习框架scikit-learn安装
1.windows环境whl包下载地址 http://www.lfd.uci.edu/~gohlke/pythonlibs/ 2.安装numpy.scipy.scikit-learn.matplotl ...
- 22、Flask实战第22天:Flask信号
Flask中的信号使用的是一个第三方插件blinker.通过pip list看一下是否安装,如果没有,则使用如下命令安装 pip install blinker 自定义信号 自定义信号分为3步: ①定 ...
- 14、Flask实战第14天:Flask使用SQLAlchemy
flask-sqlalchemy使用详解 之前我们用到的SQLAchemy是可以单独使用的,不需要用到Flask 如果我们在Flask框架中使用SQLAchemy,可以使用flask_sqlalche ...
- 棋盘V
问题 A: 棋盘V 时间限制: 1 Sec 内存限制: 128 MB提交: 150 解决: 3[提交] [状态] [讨论版] [命题人:] 题目描述 有一块棋盘,棋盘的边长为100000,行和列的 ...
- c++基础学习之string
//学习使用string类 2013-10-18 lingc #include <iostream> #include <string>//include this head ...
- bzoj4543[POI2014]Hotel
题目链接 bzoj4543 [POI2014]Hotel 题解 这不是裸地点分嘛 ,我真傻,真的 n^2 这不是是sb题,~滑稽 ~ 枚举点转换为无根树,暴力子树中点的深度 计数转移 令a b c d ...
- 洛谷 P2742 [USACO5.1]圈奶牛Fencing the Cows
题目描述 农夫约翰想要建造一个围栏用来围住他的奶牛,可是他资金匮乏.他建造的围栏必须包括他的奶牛喜欢吃草的所有地点.对于给出的这些地点的坐标,计算最短的能够围住这些点的围栏的长度. 输入输出格式 输入 ...
- codeforces 314E Sereja and Squares
discription Sereja painted n points on the plane, point number i (1 ≤ i ≤ n) has coordinates (i, 0). ...
- 【bzoj1370】【团伙】原来并查集还能这么用?!
(画师当然是武内崇啦) Description 在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足: 1. 我朋友的朋友是我的朋友: 2. 我敌人的敌人是我的朋友: 所有是朋友的人组成一 ...
- Eclipse编辑jsp卡死解决方案
使用Eclipse编辑jsp.js文件时,经常出现卡死现象,在网上百度了N次,经过N次优化调整后,卡死现象逐步好转,具体那个方法起到作用,不太好讲.将所有用过的方法罗列如下: 1.取消验证 windo ...