fcgi程序两种编写风格

转自:http://blog.csdn.net/nyist327/article/details/43792753

fcgi进程可以写成单线程的,也可以写成多线程的

单线程就是main函数中有一个死循环,一直等待接受请求,有请求过来时,就处理请求,并返回结果,没有并发性。

多线程也分两种模式:一种是main函数起多个线程,每个线程都独立接受请求。另一种是main函数起一个accpet线程接受请求,多个do_session线程处理请求,这种模式需要一个任务队列的支持。

模式不同,采用的系统架构就不同。下面就这三种模型,给出编码架构设计。

单线程模式:

 

[cpp]  view plain  copy
  1. #include <fcgi_stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string>  
  4.   
  5. int main()  
  6. {  
  7.     while(FCGI_Accept() >= 0)  
  8.     {  
  9.         string strGetData;  
  10.         int iContentLength;  
  11.         if (getenv("QUERY_STRING"))  
  12.         {  
  13.             strGetData = getenv("QUERY_STRING");  
  14.         }  
  15.         if (getenv("CONTENT_LENGTH"))  
  16.         {  
  17.             iContentLength = ::atoi(getenv("CONTENT_LENGTH"));  
  18.         }  
  19.         char* data = (char*)::malloc(iContentLength + 1);  
  20.         ::memset(data, 0, iContentLength + 1);  
  21.         FCGI_fgets(data, iContentLength + 1, FCGI_stdin);  
  22.         FCGI_printf("Content-type:text/html\r\n\r\n");  
  23.         FCGI_printf(data);  
  24.     }  
  25.     return 0;  
  26. }  

多线程模式,每个线程都独立接受请求:

 

[cpp]  view plain  copy
  1. #include <fcgi_stdio.h>  
  2. #include <stdlib.h>  
  3. #include <pthread.h>  
  4. #include <string>  
  5.   
  6. void* pthread_func(void *arg);  
  7.   
  8. int main()  
  9. {  
  10.     int iThreadNum = 10;  
  11.     for (int index = 0; index != iThreadNum; ++ index)  
  12.     {  
  13.         pthread_t pthread_id;  
  14.         pthread_create(&pthread_id, NULL, pthread_func, NULL);  
  15.     }  
  16.   
  17.     pthread_join();  
  18.     return 0;  
  19. }  
  20.   
  21. void* pthread_func(void *arg)  
  22. {  
  23.     FCGX_Request *request = NULL;  
  24.     while (1)  
  25.     {  
  26.         int rc = FCGX_Accept_r(request);  
  27.         if (rc < 0)  
  28.         {  
  29.             continue;  
  30.         }  
  31.   
  32.         string strRequestMethod;  
  33.         string strGetData;  
  34.         string strPostData;  
  35.         int iPostDataLength;  
  36.   
  37.         if (FCGX_GetParam("QUERY_STRING", request->envp))  
  38.         {  
  39.             strGetData = FCGX_GetParam("QUERY_STRING", request->envp);  
  40.         }  
  41.         if (FCGX_GetParam("REQUEST_METHOD", request->envp))  
  42.         {  
  43.             iPostDataLength = ::atoi(FCGX_GetParam("CONTENT_LENGTH", _pRequest->envp));  
  44.             char* data = (char*)malloc(iPostDataLength + 1);  
  45.             ::memset(data, 0, iPostDataLength + 1);  
  46.             FCGX_GetStr(data, iPostDataLength, _pRequest->in);  
  47.             strPostData = data;  
  48.             free(data);  
  49.         }  
  50.   
  51.         FCGX_PutS("Content-type: text/html\r\n\r\n", _pRequest->out);  
  52.         FCGX_PutS(strPostData.c_str(), _pRequest->out);  
  53.     }  
  54. }  

多线程模式,一个accpet线程,多个do_session线程:

 

[cpp]  view plain  copy
  1. #include <fcgi_stdio.h>  
  2. #include <stdlib.h>  
  3. #include <pthread.h>  
  4. #include <string>  
  5.   
  6. void* do_accept(void *arg);  
  7. void* do_session(void *arg);  
  8.   
  9. int main()  
  10. {  
  11.     pthread_t pthread_id;  
  12.     pthread_create(&pthread_id, NULL, do_accept, NULL);  
  13.     int iThreadNum = 10;  
  14.     for (int index = 0; index != iThreadNum; ++ index)  
  15.     {  
  16.         pthread_t pthread_id;  
  17.         pthread_create(&pthread_id, NULL, do_session, NULL);  
  18.     }  
  19.   
  20.     pthread_join();  
  21.     return 0;  
  22. }  
  23.   
  24. void* do_accept(void *arg)  
  25. {  
  26.     FCGX_Request *request = NULL;  
  27.     while (1)  
  28.     {  
  29.         int rc = FCGX_Accept_r(request);  
  30.         if (rc < 0)  
  31.         {  
  32.             continue;  
  33.         }  
  34.         httpRequest.put(request); //httpRequest 是一个生产者消费者模型,此处是放入任务  
  35.     }  
  36. }  
  37.   
  38. void* do_session(void *arg)  
  39. {  
  40.     while(1)      
  41.     {  
  42.         FCGX_Request *request = NULL;  
  43.         while (!request)  
  44.         {  
  45.             request = httpRequest.get(); //此处是取出任务  
  46.         }  
  47.   
  48.         string strRequestMethod;  
  49.         string strGetData;  
  50.         string strPostData;  
  51.         int iPostDataLength;  
  52.   
  53.         if (FCGX_GetParam("QUERY_STRING", request->envp))  
  54.         {  
  55.             strGetData = FCGX_GetParam("QUERY_STRING", request->envp);  
  56.         }  
  57.         if (FCGX_GetParam("REQUEST_METHOD", request->envp))  
  58.         {  
  59.             iPostDataLength = ::atoi(FCGX_GetParam("CONTENT_LENGTH", _pRequest->envp));  
  60.             char* data = (char*)malloc(iPostDataLength + 1);  
  61.             ::memset(data, 0, iPostDataLength + 1);  
  62.             FCGX_GetStr(data, iPostDataLength, _pRequest->in);  
  63.             strPostData = data;  
  64.             free(data);  
  65.         }  
  66.   
  67.         FCGX_PutS("Content-type: text/html\r\n\r\n", _pRequest->out);  
  68.         FCGX_PutS(strPostData.c_str(), _pRequest->out);  
  69.     }  
  70. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值