如何暂停/恢复Lua命令的处理

时间:2011-05-26 21:05:32

标签: c lua

我正在编写一个可以与多个服务器通信并在stdin上处理用户命令或最终使用Lua处理文件的客户端。服务器是一个自定义应用程序,因此我正在处理C中的所有通信,其中已经编写了协议的所有代码。这里有一些我现在拥有的伪代码:

int main(int argc, char **argv) {
  /* setup fd list, vars, etc */
  ...
  while (1) {
    /* process list of file descriptors to create read/write fd sets */
    ...
    select(max, &read_fds, &write_fds, NULL, NULL);
    for each file descriptor {
      if (read fd is set) {
        read data into a buffer
        if (current fd is stdin)
          process_stdin()
        else if (current fd is from server connection)
          process_remote()
      }
      if (write fd is set) {
        write data on non-blocking fd
      }
    }
  }
}

int process_stdin() {
  luaL_loadbuffer(L, stdin_buffer, len, "stdin");
  lua_pcall(L, 0, 0, 0);
}

int process_remote() {
  parse buffer into message from remote system
  if message is complete, call Lua with either a new message notification or resume
}

所以这是我的问题:如果stdin上的用户输入类似wait_for_remote_message(xyz)的内容,我该如何停止,从lua_pcall返回并进入select }循环等待更多数据?然后,process_remote如何从那一点开始恢复Lua命令?

我可以想象一个涉及pthreads的解决方案,但这对于这个应用程序来说有点过分,并且引入了很多额外的复杂性。

我还可以设想一个解决方案,其中while(1)/select循环移动到一个函数中,并从wait_for_remote_message(xyz)我跳回C并调用此函数并添加stdin某种排除清单。

有没有更好的方法来做到这一点?

1 个答案:

答案 0 :(得分:4)

这听起来像是Lua协程的完美用法,你可以调用yield来暂停执行,然后再恢复。

查看http://www.lua.org/pil/9.html了解详情

您可以执行类似

的操作
int process_stdin() {
    lua_State coroutine =  lua_newthread(L);

    luaL_loadbuffer(coroutine, stdin_buffer, len, "stdin");
    if (lua_resume(coroutine, 0) == LUA_YIELD) {
     // store coroutine somewhere global
    }
}

int process_remote() {
    // parse buffer into message from remote system

    // push the message onto the Lua stack
    lua_resume(coroutine, 1);
}