multithreading - 多线程 FastCGI 应用程序

标签 multithreading cgi fastcgi

我想编写一个 FastCGI 应用程序,它应该使用线程处理多个并发请求。我看了threaded.c SDK 附带的示例:

#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;
    char *server_name;

    FCGX_InitRequest(&request, 0, 0);

    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);

        FCGX_FPrintF(request.out,…
        …     

        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;
}

FastCGI specification有一个解释,Web 服务器将如何确定 FastCGI 应用程序支持多少连接:

The Web server can query specific variables within the application. The server will typically perform a query on application startup in order to to automate certain aspects of system configuration.

• FCGI_MAX_CONNS: The maximum number of concurrent transport connections this application will accept, e.g. "1" or "10".

• FCGI_MAX_REQS: The maximum number of concurrent requests this application will accept, e.g. "1" or "50".

• FCGI_MPXS_CONNS: "0" if this application does not multiplex connections (i.e. handle concurrent requests over each connection), "1" otherwise.



但是这个查询的返回值被硬编码到 FastCGI SDK 中,对于 FCGI_MAX_CONNS 和 FCGI_MAX_REQS 返回 1,对于 FCGI_MPXS_CONNS 返回 0。所以 threaded.c 示例永远不会收到多个连接。

我使用 lighttpd 和 nginx 测试了示例,应用程序一次只处理一个请求。如何让我的应用程序处理多个请求?或者这是错误的方法?

最佳答案

使用 http_load 测试了 threaded.c 程序。该程序在 nginx 后面运行。该程序只有一个实例正在运行。如果请求按顺序提供,我预计即使并行发送 20 个请求也需要 40 秒。以下是结果(我使用了与 Andrew Bradford 相同的数字——20、21 和 40)——

20 个请求,20 个并行,耗时 2 秒 -

$ http_load -parallel 20 -fetches 20 request.txt
20 fetches, 20 max parallel, 6830 bytes, in 2.0026 seconds
341.5 mean bytes/connection
9.98701 fetches/sec, 3410.56 bytes/sec
msecs/connect: 0.158 mean, 0.256 max, 0.093 min
msecs/first-response: 2001.5 mean, 2002.12 max, 2000.98 min
HTTP response codes:
  code 200 -- 20

21 个请求,20 个并行,耗时 4 秒 -
$ http_load -parallel 20 -fetches 21 request.txt
21 fetches, 20 max parallel, 7171 bytes, in 4.00267 seconds
341.476 mean bytes/connection
5.2465 fetches/sec, 1791.55 bytes/sec
msecs/connect: 0.253714 mean, 0.366 max, 0.145 min
msecs/first-response: 2001.51 mean, 2002.26 max, 2000.86 min
HTTP response codes:
  code 200 -- 21

40 个请求,20 个并行,耗时 4 秒 -
$ http_load -parallel 20 -fetches 40 request.txt
40 fetches, 20 max parallel, 13660 bytes, in 4.00508 seconds
341.5 mean bytes/connection
9.98732 fetches/sec, 3410.67 bytes/sec
msecs/connect: 0.159975 mean, 0.28 max, 0.079 min
msecs/first-response: 2001.86 mean, 2002.62 max, 2000.95 min
HTTP response codes:
  code 200 -- 40

因此,它证明即使 FCGI_MAX_CONNS、FCGI_MAX_REQS 和 FCGI_MPXS_CONNS 值是硬编码的,请求也是并行处理的。

当 Nginx 收到多个请求时,它会将它们全部放入 FCGI 应用程序的队列中。在发送第二个请求之前,它不会等待第一个请求的响应。在 FCGI 应用程序中,当一个线程在任何时间为第一个请求提供服务时,另一个线程不会等待第一个请求完成,它将接收第二个请求并开始处理它。等等。

因此,您将损失的唯一时间是从队列中读取请求所需的时间。与处理请求所需的时间相比,这个时间通常可以忽略不计。

关于multithreading - 多线程 FastCGI 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5829869/

相关文章:

java - 在android中的 Activity 后面运行一个线程

java - 聚合线程和线程优先级(java)

CentOS 6.4 上的 Apache2 + FastCGI + php-fpm ==> 有效,但 error_log 中出现错误

java - 我如何才能知道在我的操作系统上进行上下文切换需要多长时间?

java - 确定 Java ThreadPoolExecutor 中执行任务的优先级

javascript - 将 href perl 变量转换为普通标量变量

perl - 如何在 OSX 上覆盖 httpd.conf 中的 @INC 设置

linux - 我可以在运行时限制 CGI 脚本中允许我访问的文件夹吗?

c - 如何使用 FastCGI、nginx 和 C 访问 cookie?

perl - 如何将 Perl 代码从 mod_perl 移植到 FastCGI?