Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
LuaPlus:如何从多线程C++;? 我在Lua脚本中有一种回调函数,我想从C++的不同线程调用(0到100次/秒)。到目前为止,它基本上是工作的,但只要我在很短的时间内多次调用它,它就会使程序崩溃,导致错误,如: -As???离子失败:0,文件…LuaFunction.h,第146行或(完全随机) 我认为这是在C++完成另一个任务之前从C++调用的。对我来说,最明显的尝试(lua函数调用期间,互斥锁锁定所有线程)根本没有帮助/ 如果我每2秒只调用Lua函数一次,那么我根本不会得到任何错误(好吧,在清理部分之前,如果它达到该点,它将崩溃而不会出现特定错误)_C++_Function_Callback_Lua_Luaplus - Fatal编程技术网

LuaPlus:如何从多线程C++;? 我在Lua脚本中有一种回调函数,我想从C++的不同线程调用(0到100次/秒)。到目前为止,它基本上是工作的,但只要我在很短的时间内多次调用它,它就会使程序崩溃,导致错误,如: -As???离子失败:0,文件…LuaFunction.h,第146行或(完全随机) 我认为这是在C++完成另一个任务之前从C++调用的。对我来说,最明显的尝试(lua函数调用期间,互斥锁锁定所有线程)根本没有帮助/ 如果我每2秒只调用Lua函数一次,那么我根本不会得到任何错误(好吧,在清理部分之前,如果它达到该点,它将崩溃而不会出现特定错误)

LuaPlus:如何从多线程C++;? 我在Lua脚本中有一种回调函数,我想从C++的不同线程调用(0到100次/秒)。到目前为止,它基本上是工作的,但只要我在很短的时间内多次调用它,它就会使程序崩溃,导致错误,如: -As???离子失败:0,文件…LuaFunction.h,第146行或(完全随机) 我认为这是在C++完成另一个任务之前从C++调用的。对我来说,最明显的尝试(lua函数调用期间,互斥锁锁定所有线程)根本没有帮助/ 如果我每2秒只调用Lua函数一次,那么我根本不会得到任何错误(好吧,在清理部分之前,如果它达到该点,它将崩溃而不会出现特定错误),c++,function,callback,lua,luaplus,C++,Function,Callback,Lua,Luaplus,以下是我的代码(我尽量裁剪和简化代码,并添加了大量注释): 我对Lua的了解还不足以在Lua方面给你一个解决方案,但是这个问题的观点可能会帮助你解决这个问题 当您从Lua调用AddThread()时,会发生如下情况: 1. LuaState allocations 2. AddThread() execution 3. LuaState unwinding 当使用ThreadFunction()时 AddThread上没有互斥控制,因此在1/3和B/D之间可能会发生竞争情况。 但是,将互斥体添

以下是我的代码(我尽量裁剪和简化代码,并添加了大量注释):


我对Lua的了解还不足以在Lua方面给你一个解决方案,但是这个问题的观点可能会帮助你解决这个问题

当您从Lua调用AddThread()时,会发生如下情况:

1. LuaState allocations
2. AddThread() execution
3. LuaState unwinding
当使用ThreadFunction()时

AddThread上没有互斥控制,因此在1/3和B/D之间可能会发生竞争情况。 但是,将互斥体添加到AddThread并不能解决问题,因为它仍然会在1到3之间运行

如果仅在程序初始化时调用AddThread(),则可以在初始化完成之前阻止所有线程。如果在程序执行期间经常调用它,那么我将从单独的LuaState进行这些调用

[编辑]第二个想法:使用生产者/消费者的方法。那么C++线程就不需要运行Lua代码了。 C++建议:

//-- start Task.h --

struct Task{
  static list<Task*> runningTasks;
  static list<Task*> doneTasks;
  static pthread_mutex_t mutex;
  list<Task*>::iterator iterator;

  virtual ~Task(){}

  bool start(){
    pthread_mutex_lock(&mutex);
    bool hasSpace = runningTasks.size() < 100;
    if(hasSpace){
      runningTasks.push_front(this);
      iterator = runningTasks.begin();
      pthread_t unusedID;
      pthread_create(&unusedID, NULL, Task::threadBody, this);
    }
    pthread_mutex_unlock(&mutex);
    return hasSpace;
  }

  virtual void run() = 0;
  virtual void processResults() = 0;

protected:
  void finish(){
    pthread_mutex_lock(&mutex);
    runningTasks.erase(iterator);
    doneTasks.push_front(this);
    pthread_mutex_unlock(&mutex);
  }

  static void* threadBody(void* instance){
    Task* task = static_cast<Task*>(instance);
    task->run();
    task->finish();
    return NULL;
  }
};
//-- end Task.h --

//-- start Task.cpp --

//Instantiate Task's static attributes
pthread_mutex_t Task::mutex;
list<Task*> Task::runningTasks;
list<Task*> Task::doneTasks;

//-- end Task.cpp --

struct SumTask: public Task{
  int a, b, c;
  void run(){
    Sleep(3000);
    c = a+b;
  }
  void processResults(){
    LuaPlus::LuaFunction<int> CPP_OnMyEvent = pState->GetGlobal("LUA_OnMyEvent");
    CPP_OnMyEvent(a,b,c);
  }
}

//functions called by Lua
bool runSumTask(int a, int b){
  SumTask task* = new SumTask();
  task->a = a; task->b = b;
  bool ok = task->start();
  if(!ok)
    delete task;
  return ok;
}

int gatherResults(){
  pthread_mutex_lock(&Task::mutex);
  int totalResults = Task::doneTasks.size();
  while(Task::doneTasks.size() > 0){
    Task* t = Task::doneTasks.front();
    Task::doneTasks.pop_front();
    t->processResults();
    delete t;
  }
  pthread_mutex_unlock(&Task::mutex);
  return totalResults;
}

int main() {
    //Must initialize/destroy Task::mutex
    pthread_mutex_init(&Task::mutex, NULL);
    //...
    pthread_mutex_destroy(&Task::mutex);
}

lua状态不是线程安全的。不能同时从多个线程使用同一状态。你读过吗?@EtanReisner我不确定这是否真的适用于卢阿普勒斯。我还尝试为每个线程在LuaPlus state上创建,但根本不起作用。我认为一个新的LuaPlus状态基本上创建了一个新的脚本环境,而其他脚本环境是无法访问的。而且,互斥体的东西已经在我的代码中了,没有多大帮助。你能把调用从Lua上删除到AdToX(x,y),并从C++调用它吗?这将避免卡斯黛乐斯塔尼的大竞争问题。我可以将AdthToin函数封装到C++边上的另一个函数中,使包装函数可以用于Lua端,但我高度怀疑这会有什么区别,因为它们最终都必须导致pthRead创建()。为什么要在主循环中使用事件系统?我的程序的全部要点是它始终异步运行特定代码,所以我必须动态添加线程。我看不出有什么不同的实现方法。@Forivin Producer-consumer实际上是您所需要的。Lua在它自己的线程上,在无休止的阻塞调用循环中,给我下一个任务(),这个函数的C++端在共享队列上等待。好吧,我还不太理解代码,但我试着运行它,看看这是否是我要找的。。出现了很多错误。我能够解决大部分问题,但仍有一些问题我不太理解。我试图编译这个:但得到了这些错误:@Forivin Sry!我只有时间给你一个代码建议。无法真正编译它。现在我已经测试卡斯黛乐代码,并用一个工作版本更新了答案。@ S.RiGoCaseLalaNy代码仍然有一些问题,但这次我能够解决它们来编译它。但是,一旦我运行exe,就会出现“访问冲突”错误。下面是代码:下面是错误的屏幕截图:
1. LuaState allocations
2. AddThread() execution
3. LuaState unwinding
A. Mutex lock
B. LuaState allocations
C. LUA_OnMyEvent() execution
D. LuaState unwinding 
E. Mutex Unlock
//-- start Task.h --

struct Task{
  static list<Task*> runningTasks;
  static list<Task*> doneTasks;
  static pthread_mutex_t mutex;
  list<Task*>::iterator iterator;

  virtual ~Task(){}

  bool start(){
    pthread_mutex_lock(&mutex);
    bool hasSpace = runningTasks.size() < 100;
    if(hasSpace){
      runningTasks.push_front(this);
      iterator = runningTasks.begin();
      pthread_t unusedID;
      pthread_create(&unusedID, NULL, Task::threadBody, this);
    }
    pthread_mutex_unlock(&mutex);
    return hasSpace;
  }

  virtual void run() = 0;
  virtual void processResults() = 0;

protected:
  void finish(){
    pthread_mutex_lock(&mutex);
    runningTasks.erase(iterator);
    doneTasks.push_front(this);
    pthread_mutex_unlock(&mutex);
  }

  static void* threadBody(void* instance){
    Task* task = static_cast<Task*>(instance);
    task->run();
    task->finish();
    return NULL;
  }
};
//-- end Task.h --

//-- start Task.cpp --

//Instantiate Task's static attributes
pthread_mutex_t Task::mutex;
list<Task*> Task::runningTasks;
list<Task*> Task::doneTasks;

//-- end Task.cpp --

struct SumTask: public Task{
  int a, b, c;
  void run(){
    Sleep(3000);
    c = a+b;
  }
  void processResults(){
    LuaPlus::LuaFunction<int> CPP_OnMyEvent = pState->GetGlobal("LUA_OnMyEvent");
    CPP_OnMyEvent(a,b,c);
  }
}

//functions called by Lua
bool runSumTask(int a, int b){
  SumTask task* = new SumTask();
  task->a = a; task->b = b;
  bool ok = task->start();
  if(!ok)
    delete task;
  return ok;
}

int gatherResults(){
  pthread_mutex_lock(&Task::mutex);
  int totalResults = Task::doneTasks.size();
  while(Task::doneTasks.size() > 0){
    Task* t = Task::doneTasks.front();
    Task::doneTasks.pop_front();
    t->processResults();
    delete t;
  }
  pthread_mutex_unlock(&Task::mutex);
  return totalResults;
}

int main() {
    //Must initialize/destroy Task::mutex
    pthread_mutex_init(&Task::mutex, NULL);
    //...
    pthread_mutex_destroy(&Task::mutex);
}
function LUA_OnMyEvent(a,b,c)
  print(a.."+"..b.."="..c)
end

local totalRunning = 0;
for i=1, 999, 1 do
  if (runSumTask(i,i*2))
    totalRunning = totalRunning + 1;

  totalRunning -= gatherResults();
end

while(totalRunning > 0) do
  totalRunning -= gatherResults();
  mySleepFunction(...);
end