我还没找到异步处理的方式。如果有异步的实现方式,那就可以单线程异步处理多个并发请求了。
不过我在FastCGI的sample里面找到了多线程的方式,多线程的方式封装一下应该也可以达到异步的效果的。比如,doit()线程把 FCGX_Requestrequest丢给另一个线程A处理,然后doit()线程阻塞的等待线程A的返回结果。那么线程A实际上就可以采取异步的方式来处理请求了。
以下是FastCGI的sample里面的多线程实现:
另外, FCGX_Accept_r()可以在 FCGX_Finish_r()之前连续accept多个request,这应该也代表着一种异步的方法。不过需要构造多个request对象给 FCGX_Accept_r()。
不过我在FastCGI的sample里面找到了多线程的方式,多线程的方式封装一下应该也可以达到异步的效果的。比如,doit()线程把 FCGX_Requestrequest丢给另一个线程A处理,然后doit()线程阻塞的等待线程A的返回结果。那么线程A实际上就可以采取异步的方式来处理请求了。
以下是FastCGI的sample里面的多线程实现:
/**/
/*
*threaded.c--Asimplemulti-threadedFastCGIapplication.
*/
#ifndeflint
static const char rcsid[] = " $Id:threaded.c,v1.92001/11/2003:23:21robsExp$ " ;
#endif /*notlint*/
#include " fcgi_config.h "
#include < pthread.h >
#include < sys / types.h >
#ifdefHAVE_UNISTD_H
#include < unistd.h >
#endif
#include " fcgiapp.h "
#define THREAD_COUNT20
static int counts[THREAD_COUNT];
static void * doit( void * a)
... {
intrc,i,thread_id=(int)a;
pid_tpid=getpid();
FCGX_Requestrequest;
char*server_name;
FCGX_InitRequest(&request,0,0);
for(;;)
...{
staticpthread_mutex_taccept_mutex=PTHREAD_MUTEX_INITIALIZER;
staticpthread_mutex_tcounts_mutex=PTHREAD_MUTEX_INITIALIZER;
/**//*Someplatformsrequireaccept()serialization,somedon't..*/
pthread_mutex_lock(&accept_mutex);
rc=FCGX_Accept_r(&request);
pthread_mutex_unlock(&accept_mutex);
if(rc<0)
break;
server_name=FCGX_GetParam("SERVER_NAME",request.envp);
FCGX_FPrintF(request.out,
"Content-type:text/html "
" "
"<title>FastCGIHello!(multi-threadedC,fcgiapplibrary)</title>"
"<h1>FastCGIHello!(multi-threadedC,fcgiapplibrary)</h1>"
"Thread%d,Process%ld<p>"
"Requestcountsfor%dthreadsrunningonhost<i>%s</i><p><code>",
thread_id,pid,THREAD_COUNT,server_name?server_name:"?");
sleep(2);
pthread_mutex_lock(&counts_mutex);
++counts[thread_id];
for(i=0;i<THREAD_COUNT;i++)
FCGX_FPrintF(request.out,"%5d",counts[i]);
pthread_mutex_unlock(&counts_mutex);
FCGX_Finish_r(&request);
}
returnNULL;
}
int main( void )
... {
inti;
pthread_tid[THREAD_COUNT];
FCGX_Init();
for(i=1;i<THREAD_COUNT;i++)
pthread_create(&id[i],NULL,doit,(void*)i);
doit(0);
return0;
}
*threaded.c--Asimplemulti-threadedFastCGIapplication.
*/
#ifndeflint
static const char rcsid[] = " $Id:threaded.c,v1.92001/11/2003:23:21robsExp$ " ;
#endif /*notlint*/
#include " fcgi_config.h "
#include < pthread.h >
#include < sys / types.h >
#ifdefHAVE_UNISTD_H
#include < unistd.h >
#endif
#include " fcgiapp.h "
#define THREAD_COUNT20
static int counts[THREAD_COUNT];
static void * doit( void * a)
... {
intrc,i,thread_id=(int)a;
pid_tpid=getpid();
FCGX_Requestrequest;
char*server_name;
FCGX_InitRequest(&request,0,0);
for(;;)
...{
staticpthread_mutex_taccept_mutex=PTHREAD_MUTEX_INITIALIZER;
staticpthread_mutex_tcounts_mutex=PTHREAD_MUTEX_INITIALIZER;
/**//*Someplatformsrequireaccept()serialization,somedon't..*/
pthread_mutex_lock(&accept_mutex);
rc=FCGX_Accept_r(&request);
pthread_mutex_unlock(&accept_mutex);
if(rc<0)
break;
server_name=FCGX_GetParam("SERVER_NAME",request.envp);
FCGX_FPrintF(request.out,
"Content-type:text/html "
" "
"<title>FastCGIHello!(multi-threadedC,fcgiapplibrary)</title>"
"<h1>FastCGIHello!(multi-threadedC,fcgiapplibrary)</h1>"
"Thread%d,Process%ld<p>"
"Requestcountsfor%dthreadsrunningonhost<i>%s</i><p><code>",
thread_id,pid,THREAD_COUNT,server_name?server_name:"?");
sleep(2);
pthread_mutex_lock(&counts_mutex);
++counts[thread_id];
for(i=0;i<THREAD_COUNT;i++)
FCGX_FPrintF(request.out,"%5d",counts[i]);
pthread_mutex_unlock(&counts_mutex);
FCGX_Finish_r(&request);
}
returnNULL;
}
int main( void )
... {
inti;
pthread_tid[THREAD_COUNT];
FCGX_Init();
for(i=1;i<THREAD_COUNT;i++)
pthread_create(&id[i],NULL,doit,(void*)i);
doit(0);
return0;
}
另外, FCGX_Accept_r()可以在 FCGX_Finish_r()之前连续accept多个request,这应该也代表着一种异步的方法。不过需要构造多个request对象给 FCGX_Accept_r()。