2011-05-26 47 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