c++ - 对 FCGI 概念感到困惑

标签 c++ c fastcgi

我目前正在尝试实现一个在 Linux 上运行的小型 FastCGI 多线程应用程序。我使用来自 fastcgi.com 的库.现在我不确定我是否真的理解 web 服务器和我的应用程序之间的 FCGI 通信是如何工作的概念。

首先,我在我的应用程序中创建了一个新套接字。我返回文件描述符。

int socketIn = 0;
struct sockaddr_un local;
int length = 0;
int value = 1;

memset(&local, 0, sizeof(local));

local.sun_family = AF_UNIX;

strcpy(local.sun_path, socketPath);

length = strlen(local.sun_path) + sizeof(local.sun_family);

/* delete old unix socket */
if(-1 == unlink(socketPath))
{
    switch (errno)
    {
        case ENOENT:
        {
        }break;

        default:
        {
            printf("\n[Error]\tCould not remove old socket.");
            return -1;
        }
    }
}

/* create new socket */
if (-1 == (socketIn = socket(AF_UNIX, SOCK_STREAM, 0))) 
{
    printf("\n[Error]\tCould not create socket.");
    return -2;
}

/* bind socket */
if (-1 == bind(socketIn, (struct sockaddr *)&local, length)) 
{
    printf("\n[Error]\tCould not bind socket.");
    return -4;
}

return socketIn;

之后我初始化 FCGI 库:FCGX_Init();

现在我开始创建我的线程:

#define THREAD_COUNT 2

static int counts[THREAD_COUNT];

struct thread_data{
   int  thread_id;
   int  fcgiSocket;
};

struct thread_data thread_data_array[THREAD_COUNT];

int main(int argc, char** argv) 
{
   int i;
   pthread_t id[THREAD_COUNT];
   for (i = 1; i < THREAD_COUNT; i++)
   {
      thread_data_array[i].thread_id = i;
      thread_data_array[i].fcgiSocket = fcgi.fcgiSocket;
      pthread_create(&id[i], NULL, doit, &thread_data_array[i]);
   }

   thread_data_array[0].thread_id = 0;
   thread_data_array[0].fcgiSocket = fcgi.fcgiSocket;

   doit((void *)&thread_data_array[0]);

   return 0;
}

最后是我的线程代码:

static void *doit(void *a)
{
    struct thread_data *my_data;
    my_data = (struct thread_data *) a;
    int rc, i;
    pid_t pid = getpid();
    FCGX_Request request;
    char *server_name;

    FCGX_InitRequest(&request, my_data->fcgiSocket, 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,
            "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>",
            my_data->thread_id, pid, THREAD_COUNT, server_name ? server_name : "?");

        pthread_mutex_lock(&counts_mutex);
        ++counts[my_data->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);
    }

    return NULL;
}

现在我担心我使用的套接字。 3 个线程都将写入同一个套接字。使用多线程 FCGI 应用程序是否有其他或更好的方法来解决这个问题?

最佳答案

我正在回复旧帖子,但也许其他人可以从中受益。

"Now I'm worried about the socket I use. The 3 threads will all write to the same socket."

不用担心!

根据Fast CGI规范,每个请求都有关联的ID,当线程将响应写回socket时,它会关联其服务的请求的ID。因此,即使线程以不同的顺序写入,Web 服务器也知道哪个响应是针对哪个请求的。规范在这里-

http://www.fastcgi.com/drupal/node/6?q=node/22

并且只要消息的大小小于 PIPE_BUF,就保证对套接字的写入是原子的。并且 libfcgi 将写入大小限制为 PIPE_BUF。您可以在以下文件中查看 -

http://www.fastcgi.com/mod_fastcgi/mod_fastcgi.h

#define FCGI_MAX_MSG_LEN  PIPE_BUF

希望这个解释能解开疑惑!

关于c++ - 对 FCGI 概念感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14211689/

相关文章:

c++ - 如何将 boost::multi_array 中元素的指针转换为其索引?

c++ - 运算符重载 = 和模板 double 值仅对 int 不起作用

使用 makefile 编译 C 项目

c - 将值填充到一维数组中

django - 第一次设置django

php - 使用 PHP fastcgi 和 eclipse 配置 Xdebug?

c++ - 将字符串存储到整数数组

c++ - 使用内部迭代器从 boost 多索引中删除项目时的一致性

c - 如何使用 fscanf 读取带有分隔符的文件?

c++ - [C/C++][CGIcc] GET 有效但 POST 导致错误消息