您好,我一直在尝试制作fastcgi应用程序,我希望它是多线程的,以便它可以一次处理很多请求.我找到了代码,并对其进行了一些修改
FCGX_InitRequest(&request, 0, FCGI_FAIL_ACCEPT_ON_INTR);
for (;;)
{
static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t counts_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&accept_mutex);
rc = FCGX_Accept_r(&request);
pthread_mutex_unlock(&accept_mutex);
... ... ...
FCGX_FPrintF(request.out,"%s",test_stream.str().c_str());
FCGX_Finish_r(&request);
}
代码始终停留在接受状态,因此实际上它一直等待,直到请求完全完成为止.
我试过像这样产卵fastcgi
spawn-fcgi -p 8001 -U www-data -n handler.cgi -F 32
spawn-fcgi -p 8001 -U www-data -n handler.cgi -- /usr/bin/multiwatch -F 32
解决方法:
问题已经解决了.使用FCGX_OpenSocket和umask(0)来让套接字接受.这将为您提供真正的多线程应用程序.
#include <pthread.h>
#include <sys/types.h>
#include <stdio.h>
#include "fcgi_config.h"
#include "fcgiapp.h"
#define THREAD_COUNT 8
#define SOCKET_PATH "/var/run/myfcgiserver.sock" // your unix socket file
static int socketId;
static void *doit(void *a)
{
int rc, i;
FCGX_Request request;
char *server_name;
if(FCGX_InitRequest(&request, socketId, 0) != 0)
{
printf("Can not init request\n");
return NULL;
}
printf("Request is inited\n");
for(;;)
{
static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER;
printf("Try to accept new request\n");
pthread_mutex_lock(&accept_mutex);
rc = FCGX_Accept_r(&request);
pthread_mutex_unlock(&accept_mutex);
if(rc < 0)
{
printf("Can not accept new request\n");
break;
}
printf("request is accepted\n");
server_name = FCGX_GetParam("SERVER_NAME", request.envp);
FCGX_PutS("Content-type: text/html\r\n", request.out);
FCGX_PutS("\r\n", request.out);
FCGX_PutS("<html>\r\n", request.out);
FCGX_PutS("<head>\r\n", request.out);
FCGX_PutS("<title>FastCGI Hello! (multi-threaded C, fcgiapp library)</title>\r\n", request.out);
FCGX_PutS("</head>\r\n", request.out);
FCGX_PutS("<body>\r\n", request.out);
FCGX_PutS("<h1>FastCGI Hello! (multi-threaded C, fcgiapp library)</h1>\r\n", request.out);
FCGX_PutS("<p>Request accepted from host <i>", request.out);
FCGX_PutS(server_name ? server_name : "?", request.out);
FCGX_PutS("</i></p>\r\n", request.out);
FCGX_PutS("</body>\r\n", request.out);
FCGX_PutS("</html>\r\n", request.out);
FCGX_Finish_r(&request);
}
return NULL;
}
int main(void)
{
int i;
pthread_t id[THREAD_COUNT];
FCGX_Init();
printf("Lib is inited\n");
umask(0);
socketId = FCGX_OpenSocket(SOCKET_PATH, 2000);
if(socketId < 0)
{
return 1;
}
printf("Socket is opened\n");
for(i = 0; i < THREAD_COUNT; i++)
{
pthread_create(&id[i], NULL, doit, NULL);
}
for(i = 0; i < THREAD_COUNT; i++)
{
pthread_join(id[i], NULL);
}
return 0;
}