问题
Ey,
I'm making threading system in lua and I have a crash when I resume a lot threads... I'm noob in C Lua and I don't really know what is the good or bad what I'm doing in the next codes...
I flagged crash places with "//maybe here"
#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
回答1:
Lua has no built-in support for multithreading at the OS level. Lua threads are coroutines, not OS threads. You cannot use Lua threads of the same mother state in different OS threads. You can use separate Lua states in different OS threads but any data exchange between two states must be managed manually.
On the other hand, you can build Lua to support OS-level multithreading by defining lock and unlock macros but these will be called every time the app goes into and leaves Lua.
来源:https://stackoverflow.com/questions/17817452/lua-5-2-2-broken-threading-system