fcgi程序两种编写风格

2023-11-18

fcgi进程可以写成单线程的,也可以写成多线程的

单线程就是main函数中有一个死循环,一直等待接受请求,有请求过来时,就处理请求,并返回结果,没有并发性。

多线程也分两种模式:一种是main函数起多个线程,每个线程都独立接受请求。另一种是main函数起一个accpet线程接受请求,多个do_session线程处理请求,这种模式需要一个任务队列的支持。

模式不同,采用的系统架构就不同。下面就这三种模型,给出编码架构设计。

单线程模式:

 

#include <fcgi_stdio.h>
#include <stdlib.h>
#include <string>

int main()
{
    while(FCGI_Accept() >= 0)
    {
        string strGetData;
        int iContentLength;
        if (getenv("QUERY_STRING"))
        {
            strGetData = getenv("QUERY_STRING");
        }
        if (getenv("CONTENT_LENGTH"))
        {
            iContentLength = ::atoi(getenv("CONTENT_LENGTH"));
        }
        char* data = (char*)::malloc(iContentLength + 1);
        ::memset(data, 0, iContentLength + 1);
        FCGI_fgets(data, iContentLength + 1, FCGI_stdin);
        FCGI_printf("Content-type:text/html\r\n\r\n");
        FCGI_printf(data);
    }
    return 0;
}

多线程模式,每个线程都独立接受请求:

 

#include <fcgi_stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string>

void* pthread_func(void *arg);

int main()
{
    int iThreadNum = 10;
    for (int index = 0; index != iThreadNum; ++ index)
    {
        pthread_t pthread_id;
        pthread_create(&pthread_id, NULL, pthread_func, NULL);
    }

    pthread_join();
    return 0;
}

void* pthread_func(void *arg)
{
    FCGX_Request *request = NULL;
    while (1)
    {
        int rc = FCGX_Accept_r(request);
        if (rc < 0)
        {
            continue;
        }

        string strRequestMethod;
        string strGetData;
        string strPostData;
        int iPostDataLength;

        if (FCGX_GetParam("QUERY_STRING", request->envp))
        {
            strGetData = FCGX_GetParam("QUERY_STRING", request->envp);
        }
        if (FCGX_GetParam("REQUEST_METHOD", request->envp))
        {
            iPostDataLength = ::atoi(FCGX_GetParam("CONTENT_LENGTH", _pRequest->envp));
            char* data = (char*)malloc(iPostDataLength + 1);
            ::memset(data, 0, iPostDataLength + 1);
            FCGX_GetStr(data, iPostDataLength, _pRequest->in);
            strPostData = data;
            free(data);
        }

        FCGX_PutS("Content-type: text/html\r\n\r\n", _pRequest->out);
        FCGX_PutS(strPostData.c_str(), _pRequest->out);
    }
}

多线程模式,一个accpet线程,多个do_session线程:

 

#include <fcgi_stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string>

void* do_accept(void *arg);
void* do_session(void *arg);

int main()
{
    pthread_t pthread_id;
    pthread_create(&pthread_id, NULL, do_accept, NULL);
    int iThreadNum = 10;
    for (int index = 0; index != iThreadNum; ++ index)
    {
        pthread_t pthread_id;
        pthread_create(&pthread_id, NULL, do_session, NULL);
    }

    pthread_join();
    return 0;
}

void* do_accept(void *arg)
{
    FCGX_Request *request = NULL;
    while (1)
    {
        int rc = FCGX_Accept_r(request);
        if (rc < 0)
        {
            continue;
        }
        httpRequest.put(request); //httpRequest 是一个生产者消费者模型,此处是放入任务
    }
}

void* do_session(void *arg)
{
    while(1)    
    {
        FCGX_Request *request = NULL;
        while (!request)
        {
            request = httpRequest.get(); //此处是取出任务
        }

        string strRequestMethod;
        string strGetData;
        string strPostData;
        int iPostDataLength;

        if (FCGX_GetParam("QUERY_STRING", request->envp))
        {
            strGetData = FCGX_GetParam("QUERY_STRING", request->envp);
        }
        if (FCGX_GetParam("REQUEST_METHOD", request->envp))
        {
            iPostDataLength = ::atoi(FCGX_GetParam("CONTENT_LENGTH", _pRequest->envp));
            char* data = (char*)malloc(iPostDataLength + 1);
            ::memset(data, 0, iPostDataLength + 1);
            FCGX_GetStr(data, iPostDataLength, _pRequest->in);
            strPostData = data;
            free(data);
        }

        FCGX_PutS("Content-type: text/html\r\n\r\n", _pRequest->out);
        FCGX_PutS(strPostData.c_str(), _pRequest->out);
    }
}

工作到目前为止,只见了这三种模型,如果哪位好友有其他的模型,欢迎指点一下,在下不胜感激~~~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

fcgi程序两种编写风格 的相关文章

  • 原生 Linux 应用程序可像 ResHacker 一样编辑 Win32 PE

    我想运行自动修改 dll服务 用户提交特定的 dll 我在服务器上修改它 然后用户可以下载 dll的修改版本 是否有任何本机 Linux 应用程序提供常见的 Win32 PE 修改功能 例如图标 字符串 加速器 对话等 至少提供命令行或脚本
  • 退出 bash 脚本但保持进程运行

    我正在运行服务器 需要使用参数执行以下命令 这些脚本目前工作得很好 但问题是当我运行脚本时我无法返回到控制台 它在控制台中保持运行 如果我强行停止它 那么该过程也会停止 我想继续运行该进程并返回到控制台 bin sh php home st
  • 在中断时获取 current->pid

    我正在Linux调度程序上写一些东西 我需要知道在我的中断到来之前哪个进程正在运行 当前的结构可用吗 如果我在中断处理程序中执行 current gt pid 我是否可以获得我中断的进程的 pid 你可以 current gt pid存在并
  • 如何在两个不同帐户之间设置无密码身份验证

    我们可以在两台机器的两种不同用途之间设置无密码身份验证吗 例如 计算机A有用户A 计算机B有用户B 我们可以设置密码 ssh 以便计算机 A 上的用户 A 使用其用户帐户 A 登录计算机 B 谢谢你 如果我理解你的问题 你能设置一下吗ssh
  • 远程linux服务器到远程linux服务器大型稀疏文件复制 - 如何?

    我有两台 CentOS 5 4 服务器 每台服务器上都安装了 VMware Server 假设我始终对 vmware 虚拟机使用稀疏文件 将虚拟机文件从一台服务器复制到另一台服务器的最可靠 最快速的方法是什么 虚拟机的文件复制起来很痛苦 因
  • Xenomai 中的周期性线程实时失败

    我正在创建一个周期性线程 它在模拟输出上输出方波信号 我正在使用 Xenomai API 中的 Posix Skin 和 Analogy 我使用示波器测试了代码的实时性能 并查看了方波信号 频率为 1kHz 的延迟 我应该实现 250us
  • 如何仅将整个嵌套目录中的头文件复制到另一个目录,在复制到新文件夹后保持相同的层次结构

    我有一个目录 其中有很多头文件 h 和其他 o 和 c 文件以及其他文件 这个目录里面有很多嵌套的目录 我只想将头文件复制到一个单独的目录 并在新目录中保留相同的结构 cp rf oldDirectory newDirectory将复制所有
  • grails 上的同步块在 Windows 上有效,但在 Linux 上无效

    我有一个 grails 应用程序 它依赖于服务中的同步块 当我在 Windows 上运行它时 同步按预期工作 但当我在 ams linux 上运行时 会出现 StaleObjectStateException 该问题在以下示例中重现 cla
  • 使用命令行将 MediaWiki 维基文本格式转换为 HTML

    我倾向于编写大量文档 因此 MediaWiki 格式对我来说很容易理解 而且比编写传统 HTML 节省了我很多时间 然而 我也写了一篇博客 发现一直从键盘切换到鼠标来输入正确的 HTML 标签会增加很多时间 我希望能够使用 Mediawik
  • Gradle 1.3:build.gradle 不构建类

    这里有一个新问题 我有一个 build gradle 文件apply plugin java在其中 并与 java 项目 包关联 当我跑步时gradle build从命令行我得到 compileJava UP TO DATE process
  • R 未获取用户库

    我有一个带 R 3 6 0 的 Fedora 30 系统 用户库设置在Renviron就像这个 R LIBS USER R LIBS USER R x86 64 redhat linux gnu library 3 6 事实上 它出现在交互
  • 如何从 Linux 的 shell 中删除所有以 ._ 开头的文件?

    确实如标题所示 我已将许多文件从 Mac 复制到 Raspberry Pi 这导致了许多以前缀开头的多余文件 我想删除以以下开头的文件夹中的每个文件 我该怎么做 尝试类似的方法 cd path to directory rm rf 或者 如
  • 如何调用位于其他目录的Makefile?

    我正在尝试这样做 我想打电话给 make Makefile存在于其他目录中 abc可以使用位于不同目录中的 shell 脚本的路径 我该怎么做呢 由于 shell 脚本不允许我cd进入Makefile目录并执行make 我怎样才能编写she
  • 如何成功使用RDAP协议代替whois

    我对新的 RDAP 协议有点困惑 也不知道何时进一步追求它有意义 在我看来 每个人都同意它是 whois 的继承者 但他们的数据库似乎是空的 在 ubuntu 上我尝试了 rdapper nicinfo 甚至他们的 RESTful API
  • 构建 makefile 依赖/继承树

    如果我解释得不好或者问了一些明显的问题 我很抱歉 但我是 Linux 内核的新手 而且有点深入 我们有一个嵌入式 Linux 系统 它附带一个 文档非常糟糕的 SDK 其中包含数百个文件夹stuff 大多数文件夹包含rules make m
  • gentoo crontab:为什么这个简单的 crontab 不起作用?

    我使用 GENTOO 发行版 crontab e 35 12 root php5 home www cron php 当我手动运行时 php5 php5 home www cron php 这有效 它向我发送了一封电子邮件 然后我检查日期
  • git在Windows和Linux之间切换后强制刷新索引

    我有一个Windows和Linux共享的磁盘分区 格式 NTFS 它包含一个 git 存储库 约 6 7 GB 如果我只使用Windows or 只使用Linux操作 git 存储库一切正常 但是每次切换系统的时候git status命令将
  • 伊迪德信息

    重新定义问题 有什么方法可以获取所连接显示器的序列号吗 我想收集显示器的Eid信息 当我使用 logverbose 选项运行 X 时 我可以从 xorg 0 log 文件中获取它 但问题是 如果我切换显示器 拔出当前显示器 然后插入另一个显
  • 在 LINUX 上使用 Python 连接到 OLAP 多维数据集

    我知道如何在 Windows 上使用 Python 连接到 MS OLAP 多维数据集 嗯 至少有一种方法 通常我使用 win32py 包并调用 COM 对象进行连接 import win32com client connection wi
  • 为什么在 Linux 上字符串文字的内存地址与其他字符串文字的内存地址如此不同?

    我注意到字符串文字在内存中的地址与其他常量和变量 Linux 操作系统 非常不同 它们有许多前导零 未打印 Example const char h Hi int i 1 printf p n void h printf p n void

随机推荐

  • python中unittest+ddt的应用

    一 单个EXCEL执行 import unittest from class api login topup demo import http request from class api login topup http attr imp
  • 使用KIF进行功能性iOS UI测试

    开始使用KIF 从Github下载KIF源资产并将其放置在可以轻松找到的地方 或者 可以使用 Git 的子模块来获取本地使用的源代码 git 初始化 git submodule 添加 https github com kif framewo
  • c#的值类型和引用类型(拆装箱)

    1 值类型和引用类型 c 中所有的引用类型共同的基类是System Object 1 管理机制 值类型 操作系统负责 作用域结束时被操作系统自动释放 引用类型 垃圾回收器负责 2 内存分配 值类型 值类型实例总会被分配到变量声明的地方 声明
  • 计算机网络(3.6)数据链路层- PPP 协议的帧格式和工作状态

    PPP 协议的帧格式 PPP 帧的首部和尾部分别为 4 个字段和 2 个字段 标志字段F 0x7E 符号 0x 表示后面的字符是用十六进制表示 十六进制的7E的二进制表示是 01111110 地址字段A只置为0xFF 地址字段实际上并不起作
  • 托管函数和非托管函数如何互相传递ansi字符串?

    先来介绍两个预处理指令 pragma unmanaged pragma managed 这两个预处理指令 控制函数编译成托管函数 还是非托管函数 是函数级别的预控制指令 1 托管函数传送字符串给非托管函数 分三步走 a 先调用StringT
  • echars水状_Echarts饼状图属性设置

    标题 title text 学生生源地来源分布图 subtext 模拟数据 x 设置水平安放位置 默认左对齐 可选值 center left right number x坐标 单位px x center y 设置垂直安放位置 默认全图顶端
  • IPv6地址结构、地址分类以及表示方法

    IPv6地址的表示方法 IPv6地址总长度为128比特 通常分为8组 每组为4个十六进制数的形式 每组十六进制数间用冒号分隔 例如 FC00 0000 130F 0000 0000 09C0 876A 130B 这是IPv6地址的首选格式
  • Python从入门到精通,100天就够了!(2)——分支结构与循环结构

    文章目录 一 分支结构 选择结构 1 分支结构初体验 2 分支结构练习 二 循环结构 1 for in 循环 2 for in 循环练习 3 while 循环 4 break和continue 5 while 循环练习 6 嵌套的循环结构
  • 【零基础 快速学Java】韩顺平 p35-51 变量、数据类型(整型,浮点,字符,布尔)、重要编码,API文档

    课程 p35 51 变量 变量是程序的基本组成单位 变量有三个基本要素 类型 名称 值 变量相当于内存中一个数据存储空间的表示 通过变量名可以访问变量 值 四个常用数据类型 int double char String String的S要大
  • LuCI - 网页用户配置界面开发

    luci 参考资料 http luci subsignal org trac wiki Documentation http wiki openwrt org doc techref preinit mount first boot htt
  • 【IOS 开发学习总结-OC-4】objective-c 运算符

    运算符是用于数据运算 赋值和比较等的特殊符号 objective c 语言中的运算符有以下几种 算术运算符 赋值运算符 比较运算符 逻辑运算符 位运算符 类型相关运算符 算术运算符 有7个基本运算符 加法运算符 减法运算符 还可以作为负号使
  • Ubuntu下安装jdk1.7

    转载 http blog csdn net zth1002 article details 51383508 1 去到官网下载jdk 点击打开链接 2 安装WinSCP工具连接到Linux系统上面在 usr lib里面新建一个jvm文件夹
  • UPF与低功耗设计实现实例 -- 附UPF与DC综合脚本

    原文链接 https www eefocus com industrial electronics 473034 本文摘自 数字集成电路低功耗物理实现技术与 UPF 孙轶群 sun yiqun nationz com cn 国民技术股份有限
  • Tomcat Port8009与AJP13协议

    Tomcat最主要的功能是提供Servlet JSP容器 尽管它也可以作为独立的Java Web服务器 它在对静态资源 如HTML文件或图像文件 的处理速度 以及提供的Web服务器管理功能方面都不如其他专业的HTTP服务器 如IIS和Apa
  • java.util.ConcurrentModificationException

    错误类型 java util ConcurrentModificationException 出现原因 在foreach增强循环中进行了元素删除操作 只要是集合这样做都会出现这个问题 ConcurrentModificationExcept
  • Unity 2D人物移动实现

    Unity 2D人物移动实现 效果展示 代码 using System Collections using System Collections Generic using UnityEngine public class Parentne
  • 基础网络故障检测

    基本网络故障检测 背景 随着网络的普遍应用 客户在使用网络时随时随刻会出现网络不通或严重卡顿现象 因如今的网络应用量大且拓扑负责 好的网络故障检测方法技术支持工程师必备的小技能包 下面我分享下我学到和用到的企业网络故障检查和排错思路 问题
  • 9:00面试,9:06就出来了,问的问题实在有点变态。。。

    从小厂出来 没想到在另一家公司又寄了 到这家公司开始上班 加班是每天必不可少的 看在钱给的比较多的份上 就不太计较了 没想到5月一纸通知 所有人不准加班 加班费不仅没有了 薪资还要降40 这下搞的饭都吃不起了 还在有个朋友内推我去了一家互联
  • 你了解docker技术的意义及用途吗?

    要说2015年扩张得最快的技术 那一定要数Docker不可 随着 互联网 的被重视以及大数据 云服务的兴起 相关的技术更是如雨后春笋般冒起 当中 有很多性能优良的技术更是先赢一步 不仅进入IT者的视界 更被众多的企业委以重任 现在 就随大圣
  • fcgi程序两种编写风格

    fcgi进程可以写成单线程的 也可以写成多线程的 单线程就是main函数中有一个死循环 一直等待接受请求 有请求过来时 就处理请求 并返回结果 没有并发性 多线程也分两种模式 一种是main函数起多个线程 每个线程都独立接受请求 另一种是m