fcgi进程可以写成单线程的,也可以写成多线程的。
单线程就是main函数中有一个死循环,一直等待接受请求,有请求过来时,就处理请求,并返回结果,没有并发性。
多线程也分两种模式:一种是main函数起多个线程,每个线程都独立接受请求。另一种是main函数起一个accpet线程接受请求,多个do_session线程处理请求,这种模式需要一个任务队列的支持。
模式不同,采用的系统架构就不同。下面就这三种模型,给出编码架构设计。
单线程模式:
#include <fcgi_stdio.h> #include <stdlib.h> #include <string> int main() { while(FCGI_Accept() >= 0) { string strGetData; int iContentLength; if (getenv("QUERY_STRING")) { strGetData = getenv("QUERY_STRING"); } if (getenv("CONTENT_LENGTH")) { iContentLength = ::atoi(getenv("CONTENT_LENGTH")); } char* data = (char*)::malloc(iContentLength + 1); ::memset(data, 0, iContentLength + 1); FCGI_fgets(data, iContentLength + 1, FCGI_stdin); FCGI_printf("Content-type:text/html\r\n\r\n"); FCGI_printf(data); } return 0; }
多线程模式,每个线程都独立接受请求:
#include <fcgi_stdio.h> #include <stdlib.h> #include <pthread.h> #include <string> void* pthread_func(void *arg); int main() { int iThreadNum = 10; for (int index = 0; index != iThreadNum; ++ index) { pthread_t pthread_id; pthread_create(&pthread_id, NULL, pthread_func, NULL); } pthread_join(); return 0; } void* pthread_func(void *arg) { FCGX_Request *request = NULL; while (1) { int rc = FCGX_Accept_r(request); if (rc < 0) { continue; } string strRequestMethod; string strGetData; string strPostData; int iPostDataLength; if (FCGX_GetParam("QUERY_STRING", request->envp)) { strGetData = FCGX_GetParam("QUERY_STRING", request->envp); } if (FCGX_GetParam("REQUEST_METHOD", request->envp)) { iPostDataLength = ::atoi(FCGX_GetParam("CONTENT_LENGTH", _pRequest->envp)); char* data = (char*)malloc(iPostDataLength + 1); ::memset(data, 0, iPostDataLength + 1); FCGX_GetStr(data, iPostDataLength, _pRequest->in); strPostData = data; free(data); } FCGX_PutS("Content-type: text/html\r\n\r\n", _pRequest->out); FCGX_PutS(strPostData.c_str(), _pRequest->out); } }
多线程模式,一个accpet线程,多个do_session线程:
#include <fcgi_stdio.h> #include <stdlib.h> #include <pthread.h> #include <string> void* do_accept(void *arg); void* do_session(void *arg); int main() { pthread_t pthread_id; pthread_create(&pthread_id, NULL, do_accept, NULL); int iThreadNum = 10; for (int index = 0; index != iThreadNum; ++ index) { pthread_t pthread_id; pthread_create(&pthread_id, NULL, do_session, NULL); } pthread_join(); return 0; } void* do_accept(void *arg) { FCGX_Request *request = NULL; while (1) { int rc = FCGX_Accept_r(request); if (rc < 0) { continue; } httpRequest.put(request); //httpRequest 是一个生产者消费者模型,此处是放入任务 } } void* do_session(void *arg) { while(1) { FCGX_Request *request = NULL; while (!request) { request = httpRequest.get(); //此处是取出任务 } string strRequestMethod; string strGetData; string strPostData; int iPostDataLength; if (FCGX_GetParam("QUERY_STRING", request->envp)) { strGetData = FCGX_GetParam("QUERY_STRING", request->envp); } if (FCGX_GetParam("REQUEST_METHOD", request->envp)) { iPostDataLength = ::atoi(FCGX_GetParam("CONTENT_LENGTH", _pRequest->envp)); char* data = (char*)malloc(iPostDataLength + 1); ::memset(data, 0, iPostDataLength + 1); FCGX_GetStr(data, iPostDataLength, _pRequest->in); strPostData = data; free(data); } FCGX_PutS("Content-type: text/html\r\n\r\n", _pRequest->out); FCGX_PutS(strPostData.c_str(), _pRequest->out); } }
工作到目前为止,只见了这三种模型,如果哪位好友有其他的模型,欢迎指点一下,在下不胜感激~~~
原文地址:http://blog.csdn.net/nyist327/article/details/43792753