我想知道如何使用一个程序实例处理多个请求,这就是说,一个fcgi程序应该在一个请求得到响应后继续运行,问题是,我怎么知道环境变量中的当前请求数据不是最后一个请求中的数据。
我的想法是在解析后使用setenv
将环境变量设置为NULL
,因此当它们不是NULL
时,这意味着服务器已将它们设置为环境变量的值。新请求,但是我不确定这是否应该完成。
我知道有一些可以处理这些内容的库,使用它们更安全,但是现在我的目标只是学习fcgi在库后面的工作方式
答案 0 :(得分:0)
不清楚您的问题中“多次请求”是什么意思。
根据您的描述,我认为您希望您的FastCgi应用程序在处理完第一个请求后仍然有效,并且可以处理另一个请求。 但这就是FastCgi的本质:单个程序/服务正在“无限循环”中运行并处理所有传入的请求。 FastCGI设计保证可以正确设置Request对象(包括所有环境变量)。
旧的CGI以相反的方式工作:每次请求都会产生CGI程序的新进程(即实例)。
您极有可能热衷于并发请求。但这仍然是可能的。 不幸的是,您没有提到服务器类型,编程语言或使用的操作系统。
在C / C ++中的Unix系统上查找处理并发请求的示例非常容易。
您已经提到过,您不想使用任何库,但是我相信您必须至少使用一个实现FastCGI接口的库。最常用的是Open Market的fcgiapp。 处理并发请求是通过称为锁的多线程技术实现的。 我是“ Windows专家”,所以这是我的WINAPI和C示例:
#define THREAD_COUNT 20
#define FAST_CGI_SOCKET ":9345"
#include <locale.h>
#include "fcgiapp.h"
CRITICAL_SECTION accept_mutex;
DWORD WINAPI requestHandler()
{
int code;
FCGX_Request request;
FCGX_InitRequest(&request, 0, 0);
for (;;)
{
EnterCriticalSection(&accept_mutex);
code = FCGX_Accept_r(&request);
LeaveCriticalSection(&accept_mutex);
if (code < 0) break;
// TODO handle request
FCGX_Finish_r(&request);
}
return 0;
}
void initFastCgi() {
FCGX_Init();
FCGX_OpenSocket(FAST_CGI_SOCKET, SOMAXCONN);
}
void startThreadsAndWait() {
int i;
HANDLE threads[THREAD_COUNT];
InitializeCriticalSection(&accept_mutex);
for (i = 0; i < THREAD_COUNT; i++) {
threads[i] = CreateThread(NULL, 0, &requestHandler, NULL, 0, NULL);
}
for (i = 0; i < THREAD_COUNT; i++) {
WaitForSingleObject(threads[i], INFINITE);
}
for (i = 0; i < THREAD_COUNT; i++) {
CloseHandle(threads[i]);
}
}
void appStart() {
setlocale(LC_ALL, "en_US.utf8");
initFastCgi();
}
void freeResources() {
}
void appFinish() {
freeResources();
}
int main(void)
{
appStart();
startThreadsAndWait();
appFinish();
return 0;
}
所有魔力都围绕在accept_mutex上。
希望即使您使用其他操作系统或编程语言也有帮助