zoukankan      html  css  js  c++  java
  • lua_newthread的真正意义

    lua_newthread 这个接口,存在误导性,很多人第一次试图用它来解决多线程问题时,都会入坑。

    实际上,这个接口真正的用法,是给那些在lua更底层的某些行为(通常是递归)导致了lua的栈溢出而准备的。

    举例说明:

    我在C底层实现了重新开始这种功能,并且我将这种功能暴露给lua了,lua在某些适当的时机,会调用restart();

    restart的实现大概如下:

    static int restart(lua_State *s){

        longjmp(rem, 0);

        return 0;

    }

    使用了setjmp和longjmp来进行远跳,这种时候,实际上,lua的调用栈就存在问题了,

    不管脚本内容是什么样的,总之从C不管以任何形式进入lua虚拟机之后再到C函数restart,这之间由lua诞生的各种垃圾内存,由于没有正常返回,而不能被lua的垃圾收集器正确回收。

    随着这种行为的次数增加到一定程度,在某次进入lua vm之后,就会报栈溢出。

    而要解决这种问题的关键,就是lua_newthread

     lua_newthread的意义是新建一个调用栈,这个调用栈与某个lua vm对象共享全局环境,它本身和线程没有关系,默认的情况下,它不能解决并发问题。

    解决方案如下:

    s = lua_newthread(source);
    lua_setglobal(source, "___safe_thread_vm_"); -- 将调用栈记录到全局变量
    lua_gc(source, LUA_GCCOLLECT); -- 垃圾回收,上一次的调用栈,会在此时被完全回收。

    source就是主对象,也就是由luaL_newstate正常创建的lua对象,加载文件,初始化什么的,都由它在程序一开始的时候处理好,在之后进入虚拟机都是 s

  • 相关阅读:
    WPA/WPA2无法暴力破解
    被书本知识所边缘化的软件工程师
    栈和队列
    Oracle update 之部分更新
    SAAS之初体验
    Entity Framework
    ResourceWriter和ResxResourceWriter的區別
    C#中將顏色轉換成網頁16進制顏色代碼
    Javascript功能代码收集(不断更新中...)
    .net1.1转换成更高版本的问题总结
  • 原文地址:https://www.cnblogs.com/babypapa/p/12527764.html
Copyright © 2011-2022 走看看