- 浏览: 300420 次
- 性别:
- 来自: 山西
博客专栏
-
天天编程
浏览量:21529
最新评论
-
变脸小伙:
运用到了场景中,希望接力
StringBuffer源码理解 -
fangsj:
IE9 安全设置 把这个禁用掉了
spring mvc 文件上传+本地预览+一次提交 -
xu-ch:
今天面试,遇到这题,求出了相似度,面试官问我算法原理是什么,悲 ...
计算字符串相似度算法——Levenshtein -
flywangfei:
你是创新工场的么?
计算字符串相似度算法——Levenshtein -
scwuwei:
六点起床比较好
《4点起床-最养生和高效的时间管理》读书笔记
0.背景
在项目中加入了等待通讯的内容,所以原来单个请求处理时间增加了。单线程处理的fcgi就会浪费CPU和用户时间,所以需要多线程来处理,减少用户排队时间。
将处理用户请求的部分从单线程变为多线程,需要大概了解改动会不会影响性能。
得到的结论是:多线程和单线程在执行的流程和使用方法几乎一样,所以多线程不会带来额外的负担。
1.单线程的处理步骤
1.1一个简单的单线程fcgi请求
#include <fcgi_stdio.h> void main(void) { int count = 0; while(FCGI_Accept() >= 0) { printf("Content-type: text/html\r\n"); printf("\r\n"); printf("Hello world!<br>\r\n"); printf("Request number %d.", count++); } exit(0); }
1.2进入FCGI_Accept。
进入这个 FCGI_Accept() 方法里面,在文件fcgi_stdio.c里。
int FCGI_Accept(void) { //变量表示是否接收请求。默认为Fasle,不接收请求 if(!acceptCalled) { //判断是否为cgi,变量为全局静态的,下次还会用。 isCGI = FCGX_IsCGI(); //状态改为接收请求。 acceptCalled = TRUE; //请求的收尾,将数值清空赋初值。 atexit(&FCGI_Finish); } else if(isCGI) { //不是第一次请求,并且是cgi程序。 return(EOF); } if(isCGI) { //cgi的初始赋值操作,不关心。 ... } else { FCGX_Stream *in, *out, *error; //char** 字符串数组。 FCGX_ParamArray envp; //接受请求,这个方法下面介绍 int acceptResult = FCGX_Accept(&in, &out, &error, &envp); //接收失败,返回<0,这也是为什么在循环上判断是 while(FCGI_Accept() >= 0) if(acceptResult < 0) { return acceptResult; } //将得到的数据赋值给对应的输出,输入,data。 FCGI_stdin->stdio_stream = NULL; FCGI_stdin->fcgx_stream = in; FCGI_stdout->stdio_stream = NULL; FCGI_stdout->fcgx_stream = out; FCGI_stderr->stdio_stream = NULL; FCGI_stderr->fcgx_stream = error; environ = envp; } //结束 return 0; }
1.3 FCGX_Accept (&in, &out, &error, &envp)
等待接收请求的方法,在fcgiaoo.c里。
static FCGX_Request the_request; int FCGX_Accept(FCGX_Stream **in,FCGX_Stream **out,FCGX_Stream **err,FCGX_ParamArray *envp) { int rc;//定义返回的变量。 //是否初始化过。 if (! libInitialized) { rc = FCGX_Init(); if (rc) { return rc; } } //接收数据,下面介绍 rc = FCGX_Accept_r(&the_request); //给对应流和数据赋值。 *in = the_request.in; *out = the_request.out; *err = the_request.err; *envp = the_request.envp; return rc; }
1.4 FCGX_Accept_r (),同在fcgiapp.c里面;
/* *---------------------------------------------------------------------- * * FCGX_Accept_r -- * * 从http server 接收一个新的请求 * Results: * 正确返回0,错误返回-1. * Side effects: * * 通过FCGX_Accept完成请求的接收,创建input,output等流并且各自分配给in * ,out,err.创建参数数据从FCGX_GetParam中取出,并且给envp。 * 不要保存指针和字符串,他们会在下次请求中的FcGX_Finish中被释放。 *---------------------------------------------------------------------- */ int FCGX_Accept_r(FCGX_Request *reqDataPtr) { if (!libInitialized) { return -9998; } //将当前的reqData完成请求。将内容释放,初始化。 FCGX_Finish_r(reqDataPtr); //while for (;;) { //ipcFd 是双方通讯的管道,在上面的FCGX_Finish_r中被赋值-1。 if (reqDataPtr->ipcFd < 0) { int fail_on_intr = reqDataPtr->flags & FCGI_FAIL_ACCEPT_ON_INTR; //接收一次请求,传入socket,没有请求会在这里等待。这里面是重点,可是我看不懂。 reqDataPtr->ipcFd = OS_Accept(reqDataPtr->listen_sock, fail_on_intr, webServerAddressList); if (reqDataPtr->ipcFd < 0) { return (errno > 0) ? (0 - errno) : -9999; } } reqDataPtr->isBeginProcessed = FALSE; reqDataPtr->in = NewReader(reqDataPtr, 8192, 0); FillBuffProc(reqDataPtr->in); if(!reqDataPtr->isBeginProcessed) { goto TryAgain; } { //查看请求类型。 char *roleStr; switch(reqDataPtr->role) { case FCGI_RESPONDER: roleStr = "FCGI_ROLE=RESPONDER"; break; case FCGI_AUTHORIZER: roleStr = "FCGI_ROLE=AUTHORIZER"; break; case FCGI_FILTER: roleStr = "FCGI_ROLE=FILTER"; break; default: goto TryAgain; } //创建存储参数QueryString的空间。 reqDataPtr->paramsPtr = NewParams(30); //将请求类型当做key-value加入参数里。 PutParam(reqDataPtr->paramsPtr, StringCopy(roleStr)); } //将输入流以制定的方式读取(在哪停止,是否需要跳过请求) SetReaderType(reqDataPtr->in, FCGI_PARAMS); //将参数读取写入key=value。 if(ReadParams(reqDataPtr->paramsPtr, reqDataPtr->in) >= 0) { //跳出循环,否则等下一次请求。 break; } //释放这些中间产生的东西。将ipcFd置为-1. TryAgain: FCGX_Free(reqDataPtr, 1); } /* for (;;) */ //将剩下的信息赋值。完成一个请求的开始部分。 SetReaderType(reqDataPtr->in, FCGI_STDIN); reqDataPtr->out = NewWriter(reqDataPtr, 8192, FCGI_STDOUT); reqDataPtr->err = NewWriter(reqDataPtr, 512, FCGI_STDERR); reqDataPtr->nWriters = 2; reqDataPtr->envp = reqDataPtr->paramsPtr->vec; return 0; }
1.5 在接收请求之前执行的FCGX_Finish_r (reqDataPtr),在fcgiapp.c里;
void FCGX_Finish_r(FCGX_Request *reqDataPtr) { int close; if (reqDataPtr == NULL) { return; } close = !reqDataPtr->keepConnection; if (reqDataPtr->in) { close |= FCGX_FClose(reqDataPtr->err); close |= FCGX_FClose(reqDataPtr->out); close |= FCGX_GetError(reqDataPtr->in); } FCGX_Free(reqDataPtr, close); }
基本结束了,只能看懂流程。
二 多线程的请求
2.1多线程请求例子
官网多线程的例子,(http://www.fastcgi.com/devkit/examples/threaded.c)
去掉多余的输出。
#define THREAD_COUNT 20 static int counts[THREAD_COUNT]; static void *doit(void *a) { int rc; FCGX_Request request; FCGX_InitRequest(&request, 0, 0); for (;;) { rc = FCGX_Accept_r(&request); if (rc < 0) break; FCGX_FPrintF(request.out, "Content-type: text/html\r\n" "\r\n" "<title>FastCGI Hello! "); sleep(2); FCGX_Finish_r(&request); } return NULL; } int main(void) { int i; pthread_t id[THREAD_COUNT]; FCGX_Init(); for (i = 1; i < THREAD_COUNT; i++) pthread_create(&id[i], NULL, doit, (void*)i); doit(0); return 0; }
2.2和fcgi有关的方法
在main方法里
FCGX_Init(); Initilize the FCGX library. This is called by FCGX_Accept() but must be called by the user when using FCGX_Accept_r().
在多线程里:
FCGX_Request request; FCGX_InitRequest(&request, 0, 0); while(){ rc = FCGX_Accept_r(&request); FCGX_FPrintF(request.out,""); FCGX_Finish_r(&request); }
3.结束
刚刚开始用C语言,希望说错的地方大家提出来。
发表评论
-
crc循环校验原理和实现
2012-03-29 23:33 192801.CRC简介 CRC(cyclical redundanc ... -
TreeMap源码理解
2012-01-31 10:44 01.首先看构造方法 public TreeMap() { ... -
HashMap源码理解
2012-01-30 21:33 1843看看HashMap对应的源码。 1.类、接口关系 ... -
StringUtils源码理解(下)
2012-01-16 15:46 2200本文介绍StringUtils的剩下的两个方法 1. ... -
StringUtils源码理解(中)有点意思的方法
2012-01-12 00:17 3635这次不按照前面的介绍了,方法都大同小异,下面就介绍几个有意思一 ... -
StringUtils源码理解(上)
2012-01-11 23:08 4744StringUtils 源码,使用的是commons-lang ... -
Properties源码理解
2012-07-05 12:23 3857Properties用来读配置文件 ... -
字符流(一)Reader和Writer源码理解
2011-11-27 20:32 14601.Reader 1.1 继承关系 public ... -
字符流(二)BufferedReader和BufferedWriter源码理解
2011-11-27 20:33 47921.BufferedReader 1.1 继承关系 ... -
DataInputStream和DataOutputStream源码理解
2011-11-17 00:02 43801.FilterInputStream简介 列出主要的内 ... -
InputStream,OutputStream源码理解
2011-11-09 22:50 33691.理解字节流和字符流 按流的形式分: 字节流和字符流。 ... -
File源码理解
2011-11-07 23:55 43311.构造函数 最基本的构 ... -
Thread源码理解
2011-10-23 14:36 43101.首先看一下Runnable接口 ... -
泛型简单回顾
2011-09-06 23:36 1288泛型的简介 1.java引入泛型的好处是安全简单。 2. ... -
LinkedList源码理解
2011-08-31 00:26 1408LinkedList源码 0.首先这个类中的两个变量 ... -
Vector源码理解
2011-08-29 23:44 1507Vector类 1.系统的变量 //记录元素的数组 pr ... -
ArrayList源码理解
2011-08-15 21:02 1696构造方法: ... -
Arrays源码理解
2011-08-15 20:34 13361.equals public static boo ... -
StringBuffer源码理解
2011-06-22 19:39 5653StringBuffer 存储和操作字符串 它所继承实现的类 ...
相关推荐
java多线程tcp socket server源码
luafcgid是在BSD / Linux下运行的多线程FastCGI服务器。 它管理许多独立的,持久的Lua状态,然后从文件系统中加载Lua脚本。 这些脚本可按需加载/初始化,并在内存中保留尽可能长的时间。 还允许Lua脚本与FastCGI库...
java多线程tcp socket server源码
java多线程tcp socket server源码
java多线程tcp socket server源码
java多线程tcp socket server源码
java多线程tcp socket server源码FastCGI 开发者工具包自述文件 $Id: README,v 1.23 2003/06/22 00:51:26 robs Exp $ Copyright (c) 1996 Open Market, Inc. See the file "LICENSE.TERMS" for information on usage...
java多线程tcp socket server源码
java多线程tcp socket server源码
所以是否使用Thread Safe(线程安全),主要看web server所采用的PHP请求处理方式,如果是多线程处理如IIS的ISAPI方式,那么请选择线程安全,如果是FastCGI那么选择非线程安全。 最终建议:IIS下,使用ISAPI方式运行...
java多线程tcp socket server源码
java多线程tcp socket server源码
java多线程tcp socket server源码
特点是:多线程 效率较高 但不够稳定 3 FastCGI方式加载PHP环境 在IIS环境里并不常见 但其它系统环境应用还是有的 不过IIS7 0开始内置FastCGI了 ">我们知道php配置有几种: 1 CGI方式加载PHP环境 通常就是IIS...
第四部分(第9~11章)主要是多线程、进程和进程间通信相关的知识,包括多线程的使用、多线程的同步和重入问题,进程方面有父子进程、僵死进程、守护进程和进程间通讯的方式。 第五部分(第12章)主要是HTTP协议的...
第四部分(第9~11章)主要是多线程、进程和进程间通信相关的知识,包括多线程的使用、多线程的同步和重入问题,进程方面有父子进程、僵死进程、守护进程和进程间通讯的方式。 第五部分(第12章)主要是HTTP协议的...
第四部分(第9~11章)主要是多线程、进程和进程间通信相关的知识,包括多线程的使用、多线程的同步和重入问题,进程方面有父子进程、僵死进程、守护进程和进程间通讯的方式; 第五部分(第12章)主要是HTTP协议的...
第四部分(第9~11章)主要是多线程、进程和进程间通信相关的知识,包括多线程的使用、多线程的同步和重入问题,进程方面有父子进程、僵死进程、守护进程和进程间通讯的方式。 第五部分(第12章)主要是HTTP协议的...
java多线程tcp socket server源码FastCGI 开发者工具包自述文件 $Id: README,v 1.21 2003/01/19 17:19:41 robs Exp $ Copyright (c) 1996 Open Market, Inc. See the file "LICENSE.TERMS" for information on usage...
特点是:多线程,效率较高,但不够稳定。 3、FastCGI方式加载PHP环境,在IIS环境里并不常见,但其它系统环境应用还是有的,不过IIS7.0开始内置FastCGI了。 特点是:高效率,高稳定性,属于将来发展趋势。 我试过...