在 《用C++實現相似於JAVA HttpServlet 的編程接口 》 文章中講了如何用 HttpServlet 等相關類編寫 CGI 程序,因而有網友提出了 CGI 程序低效性,不錯,確實 CGI 程序的進程開銷是比較大的,本文就將說明依然是這些 HTTP 相關的類,若是在使用 acl_cpp/src/master 下的服務器框架類的條件下,能夠很是方便地轉爲服務器程序。如今依然是使用 《用C++實現相似於JAVA HttpServlet 的編程接口 》示例中的 http_servlet 類,只是稍微修改一下 main 函數,就變成下面的情形:編程
////////////////////////////////////////////////////////////////////////// class master_service : public acl::master_proc { public: master_service() {} ~master_service() {} protected: // 基類虛函數,當接收到一個 HTTP 客戶端請求時,服務器 // 框架回調此函數將鏈接流傳入 virtual void on_accept(acl::socket_stream* stream) { // HttpServlet 的子類實例 http_servlet servlet("127.0.0.1:11211"); servlet.setLocalCharset("gb2312"); // 設置本地字符集 servlet.doRun(stream); // 開始處理瀏覽器請求過程 } }; ////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { acl::acl_cpp_init(); // 初始化 acl_cpp 庫 master_service service; // 半駐留進程池服務類對象 // 開始運行 if (argc >= 2 && strcmp(argv[1], "alone") == 0) { // 當在手工調試時通常採用此方式 printf("listen: 127.0.0.1:8888 ...\r\n"); service.run_alone("127.0.0.1:8888", NULL, 1); // 單獨運行方式 } else // 生產環境中以半駐留進程池模式運行 service.run_daemon(argc, argv); // acl_master 控制模式運行 return 0; }
上面的例子是一個結合 HttpServlet 類及 master_service 進程池服務類的 HTTP 服務器程序,關於進程池的例子,能夠先結合本人原來寫過的基於C語言庫 acl 的一篇文章《快速建立你的服務器程序--single進程池模型 》。瀏覽器
不只能夠很是容易地將 HttpServlet 寫成進程池方式,同時還能夠結合 acl_cpp 的線程池框架模板,將 HttpServlet 類實現爲半駐留線程池實例,下面就顯示了這一過程:服務器
class master_threads_test : public acl::master_threads { public: master_threads_test() {} ~master_threads_test() {} protected: // 基類純虛函數:當客戶端鏈接有數據可讀或關閉時回調此函數,返回 true 表示 // 繼續與客戶端保持長鏈接,不然表示須要關閉客戶端鏈接 virtual bool thread_on_read(acl::socket_stream* stream) { // HttpServlet 的子類實例 http_servlet servlet; servlet.setLocalCharset("gb2312"); // 設置本地字符集 servlet.doRun(「127.0.0.1:11211」, stream); // 開始處理瀏覽器請求過程,同時設置 memcached 的監聽地址及客戶端鏈接流 } // 基類虛函數:當接收到一個客戶端請求時,調用此函數,容許 // 子類事先對客戶端鏈接進行處理,返回 true 表示繼續,不然 // 要求關閉該客戶端鏈接 virtual bool thread_on_accept(acl::socket_stream*) { return true; // 返回 true 以容許服務器框架繼續調用 thread_on_read 過程 } }; // 字符串類配置參數項 static char *var_cfg_debug_msg; static acl::master_str_tbl var_conf_str_tab[] = { { "debug_msg", "test_msg", &var_cfg_debug_msg }, { 0, 0, 0 } }; // 布爾配置參數項 static int var_cfg_debug_enable; static int var_cfg_keep_alive; static int var_cfg_loop; static acl::master_bool_tbl var_conf_bool_tab[] = { { "debug_enable", 1, &var_cfg_debug_enable }, { "keep_alive", 1, &var_cfg_keep_alive }, { "loop_read", 1, &var_cfg_loop }, { 0, 0, 0 } }; // 整數配置參數項 static int var_cfg_io_timeout; static acl::master_int_tbl var_conf_int_tab[] = { { "io_timeout", 120, &var_cfg_io_timeout, 0, 0 }, { 0, 0 , 0 , 0, 0 } }; int main(int argc, char* argv[]) { master_threads_test mt; // 半駐留線程池服務器實例 // 設置配置參數表 mt.set_cfg_int(var_conf_int_tab); mt.set_cfg_int64(NULL); mt.set_cfg_str(var_conf_str_tab); mt.set_cfg_bool(var_conf_bool_tab); // 開始運行 if (argc >= 2 && strcmp(argv[1], "alone") == 0) { // 當在手工調試時通常採用此方式 printf("listen: 127.0.0.1:8888\r\n"); mt.run_alone("127.0.0.1:8888", NULL, 2, 10); // 單獨運行方式 } else // 生產環境中以半駐留線程池模式運行 mt.run_daemon(argc, argv); // acl_master 控制模式運行 return 0; }
該例子顯示了一個基於線程池服務器模型的WEB實例,能夠依然使用了文章 《用C++實現相似於JAVA HttpServlet 的編程接口 》示例中的 http_servlet 類,但採用的是由文章 《 開發多線程進程池服務器程序---acl 服務器框架應用 》所介紹的多進程多線程服務器框架模板。多線程
我的微博:http://weibo.com/zsxxsz框架
參考:socket
使用 acl::master_proc 類編寫多進程服務器程序memcached
使用 acl::master_threads 類編寫多進程多線程服務器程序函數
acl 下載oop
原文地址 spa
QQ 羣:242722074