因为需要就看了一下FCGI多线程例子,下面直接来看FCGI提供给我们的多线程例子吧。
/*
* threaded.c -- A simple multi-threaded FastCGI application.
*/
#ifndef lint
static const char rcsid[] = "$Id: threaded.c,v 1.9 2001/11/20 03:23:21 robs Exp $";
#endif /* not lint */
#include "fcgi_config.h"
#include <pthread.h>
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "fcgiapp.h"
#define THREAD_COUNT 20
static int counts[THREAD_COUNT];
static void *doit(void *a)
{
int rc, i, thread_id = (int)a;
pid_t pid = getpid();
FCGX_Request request; //定义一个request变量,包含了输入输出。
char *server_name;
FCGX_InitRequest(&request, 0, 0); //初始化request
char *querystring = FCGX_GetParam("QUERY_STRING", request.envp); //得到获取数据的长度
long len = strtol(contentLength, NULL, 10); //将contentLength转换为十进制long类型
for (;;)
{
static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t counts_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Some platforms require accept() serialization, some don'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); //从环境变量中获取server_name
//输出
FCGX_FPrintF(request.out,
"Content-type: text/html\r\n"
"\r\n"
"<title>FastCGI Hello! (multi-threaded C, fcgiapp library)</title>"
"<h1>FastCGI Hello! (multi-threaded C, fcgiapp library)</h1>"
"Thread %d, Process %ld<p>"
"Request counts for %d threads running on host <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);
//释放掉request
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;
}
在 FCGX中我们要使用FCGX_GetChar(request.in); 来获取标准输入中的数据。
FCGX将标准输入输出标准错误重定向的这个结构体中
typedef struct FCGX_Request {
int requestId; /* valid if isBeginProcessed */
int role;
FCGX_Stream *in; //标准输入
FCGX_Stream *out; //标准输出
FCGX_Stream *err; //标准错误
char **envp; //环境变量
/* Don't use anything below here */
struct Params *paramsPtr;
int ipcFd; /* < 0 means no connection */
int isBeginProcessed; /* FCGI_BEGIN_REQUEST seen */
int keepConnection; /* don't close ipcFd at end of request */
int appStatus;
int nWriters; /* number of open writers (0..2) */
int flags;
int listen_sock;
int detached;
} FCGX_Request;
当我们想要从标准输入中读取数据时可以使用
DLLAPI int FCGX_GetChar(FCGX_Stream *stream);
函数来读取数据,一次只会读取一个字符。











网友评论