我正在编写一个可以与多个服务器通信并在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
某种排除清单。
有没有更好的方法来做到这一点?
答案 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);
}