【问题标题】:Lua 5.2.2 Broken Threading SystemLua 5.2.2 断线系统
【发布时间】:2013-07-22 22:50:13
【问题描述】:

喂,

我在 lua 中制作线程系统,当我恢复很多线程时我崩溃了...... 我是 C Lua 的菜鸟,我真的不知道在接下来的代码中我在做什么是好是坏......

我用“//也许在这里”标记了崩溃地点

#include<cstdio>
#include<ala_lua.h>

extern"C"{
    void __stdcall Sleep(unsigned long);
};



int main(){
    lua_State*L=luaL_newstate();
    luaL_openlibs(L);
    luaA_libs(L);

    lua_State*T=lua_newthread(L);
    luaL_loadfile(T,"c:/clua.lua");
    co_resume(T);

    do{
        Sleep(1);
    }while(co_update());

    lua_close(L);

    gets(new char[1]);
    return 0;
};

#ifndef ALA_LUA_H
#define ALA_LUA_H

#include<ala_lua_co.h>

void luaA_libs(lua_State*);

static int luaA_sleep(lua_State*handle){
    co_sleep(handle,lua_tointeger(handle,1));
    return 0;
};

static int luaA_rthread(lua_State*handle){
    if(lua_isthread(handle,1)){
        co_resume(lua_tothread(handle,1));
    };
    return 0;
};

static int luaA_mthread(lua_State*handle){
    if(lua_isfunction(handle,1)){
        lua_State*thread=lua_newthread(handle);

        lua_pushvalue(handle,1);
        lua_xmove(handle,thread,1);

        return 1;
    };
    return 0;
};

void luaA_libs(lua_State*handle){
    lua_register(handle,"mthread",luaA_mthread);
    lua_register(handle,"rthread",luaA_rthread);
    lua_register(handle,"sleep",luaA_sleep);
};

#endif

#ifndef ALA_LUA_CO_H
#define ALA_LUA_CO_H

#include<vector>
#include<time.h>
#include<stdio.h>
#include<cstring>
#include<lua.hpp>

std::vector<lua_State*>co_threads;
std::vector<time_t*>co_threads_delay;

static const size_t CO_NPOS=-1;

bool co_update();
size_t co_new(lua_State*);
size_t co_get(lua_State*);
void co_resume(lua_State*);
void co_report(lua_State*);
void co_rem(lua_State*,size_t);
void co_sleep(lua_State*,time_t);
void co_remifdead(lua_State*,size_t);



void co_remifdead(lua_State*handle,size_t index=CO_NPOS){
    switch(lua_status(handle)){
        case LUA_OK:{
            if(lua_gettop(handle)==0)co_rem(handle,index);
            return;
        };
        case LUA_ERRRUN:{
            co_rem(handle,index);
            return;
        };
    };
};

void co_rem(lua_State*handle,size_t index=CO_NPOS){
    if(index==CO_NPOS){
        index=co_get(handle);
    };
    if(index!=CO_NPOS){
        co_threads.erase(co_threads.begin()+index);
        delete[]co_threads_delay[index];
        co_threads_delay.erase(co_threads_delay.begin()+index);
    };
};

bool co_update(){
    if(co_threads.empty())return false;
    size_t i=co_threads.size();
    while(i>0){
        --i;

        lua_State*handle=co_threads[i];
        if(lua_status(handle)==LUA_YIELD){
            if(*co_threads_delay[i]<=clock()){
                lua_resume(handle,NULL,0);//here maybe
                co_remifdead(handle,i);
            };
        }else{
            co_remifdead(handle,i);
        };
    };
    return!co_threads.empty();
};

void co_resume(lua_State*handle){
    switch(lua_status(handle)){
        case LUA_YIELD:{
            lua_resume(handle,NULL,0);
            co_remifdead(handle);
            return;
        };
        case LUA_OK:{
            if(lua_gettop(handle)!=0){
                size_t index=co_new(handle);
                lua_resume(handle,NULL,0);//here maybe
                co_remifdead(handle,index);
                return;
            }else{return;};
        };
        default:{return;};
    };
};

void co_sleep(lua_State*handle,time_t slp){
    size_t index=co_get(handle);
    if(index!=CO_NPOS){
        *co_threads_delay[index]=slp+clock();
        lua_yield(co_threads[index],0);
    };
};

void co_report(lua_State*handle){
    if(lua_status(handle)==LUA_ERRRUN){
        const char*error=lua_tostring(handle,-1);
        #ifdef ALA_LUA_ERRLOG
            FILE*file=fopen(ALA_LUA_ERRLOG,"a");
                fputs(error,file);
            fclose(file);
        #else
            puts(error);
        #endif
        lua_pop(handle,-1);
    };
};

size_t co_get(lua_State*handle){
    if(co_threads.empty())return CO_NPOS;
    const size_t l=co_threads.size();
    for(size_t i=0;i<l;++i){
        if(co_threads[i]==handle)return i;
    };
    return CO_NPOS;
};

size_t co_new(lua_State*handle){
    if(lua_status(handle)==LUA_OK&&lua_gettop(handle)!=0){
        time_t*tm=new time_t[1];
        co_threads.push_back(handle);
        co_threads_delay.push_back(tm);
        return co_threads.size()-1;
    };
    return CO_NPOS;
};

#endif

【问题讨论】:

  • 你能提供崩溃的回溯吗?
  • 没有研究工作,没有错误消息,没有堆栈跟踪。你实际上期待什么?这甚至不是一个真正的问题。
  • 我的问题是为什么我的程序崩溃了...我通过关闭垃圾收集解决了...稍后我会检查如何在不关闭垃圾收集的情况下保存线程

标签: multithreading crash lua system coroutine


【解决方案1】:

Lua 在操作系统级别没有对多线程的内置支持。 Lua 线程是协程,而不是操作系统线程。你不能在不同的操作系统线程中使用相同母态的 Lua 线程。您可以在不同的 OS 线程中使用单独的 Lua 状态,但两种状态之间的任何数据交换都必须手动管理。

另一方面,您可以通过定义锁定和解锁宏来构建 Lua 以支持操作系统级别的多线程,但每次应用进入和离开 Lua 时都会调用这些宏。

【讨论】:

  • 如果你读过我的代码,你应该知道我知道协程是什么......无论如何,感谢你写的最后一部分......我想我得做点什么了东西grr ...
猜你喜欢
  • 2013-10-04
  • 2013-09-11
  • 2018-07-30
  • 2012-02-06
  • 2013-04-04
  • 1970-01-01
  • 1970-01-01
  • 2011-08-27
  • 2021-06-30
相关资源
最近更新 更多