2011-05-26 72 views
1

我正在编写一个客户端,它可以与多个服务器通信,并使用Lua处理stdin或最终从一个文件处理用户命令。该服务器是一个自定义应用程序,所以我正在处理所有在C中的通信,其中该协议的所有代码已经写入。这里是什么,我现在有一个位的伪代码:如何暂停/恢复Lua命令的处理

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加入某种排除列表的解决方案。

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

回答

3

这听起来像是对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); 
} 
+0

我可以在从'lua_pcall'产生?或者,有没有办法在'luaL_loadbuffer'而不是'lua_pcall'之后执行'lua_resume'?我同意coroutines听起来像一个完美的匹配,但我错过了我在处理'stdin'与协程的链接方式。 – BMitch 2011-05-26 23:55:00

+0

嗯,在查看一些文档之后,看起来第二个问题的答案是肯定的,因为luaL_loadbuffer正在返回一个函数。让我做一些测试,看看我能否得到这个工作。谢谢Wossname。 – BMitch 2011-05-27 00:24:05

+0

它看起来像这个工作。再次感谢Wossname! – BMitch 2011-05-27 02:30:34