1、概述
本节主要描述了以进程池模式创建服务器程序的过程,而该进程池框架是以 acl_master 模板为管理进程,以 acl_single_server 单一进程池模式为半驻留进程池模板创建的。该进程池模型有如下特点:
1.1)半驻留进程池特征;
1.2)一个网络连接对应一个工作进程。
2、创建过程(以 acl_project/samples/master/single_echo 为例,ACL库是跨平台的,但 acl_master 服务器框架仅能运行在UNIX平台下)
在acl_project/samples/master/single_echo/ 目录下存放着一个以 acl_single_server 为服务器模型的echo服务程序。在该目录下应该有 main.c, app_log.c, app_log.h, Makefile, Makefile.elib 四个文件,所需要修改的只是 main.c 文件,其它几个文件无须修改。
2.1)编写源文件
a)包含 ACL 库的头文件: #include "lib_acl.h"
b)调用服务函数 acl_single_server_main() 并注册相关函数:
函数原型:void acl_single_server_main(int argc, char **argv, ACL_SINGLE_SERVER_FN service,...);
argc, argv: 是 main() 入口的两个参数;
service :是用户自己的服务工作函数指针,该函数是以注册函数的方式注册进服务框架模板并由服务框架调用的;
...:是一些不定参数,这些参数都是可选的,这些不定参数是以“类型:指针”的方式传递给服务框架的,由服务框架根据类型自动进行分析,常用类型有:
ACL_MASTER_SERVER_INT_TABLE--为int类型的配置项集合的结构数组指针(该类型与由框架读取用户所需要的配置项相关);
ACL_MASTER_SERVER_STR_TABLE--字符串类型的配置项集合的结构数组指针(该类型与由框架读取用户所需要的配置项相关);
ACL_MASTER_SERVER_BOOL_TABLE--布尔类型的配置项集合的结构数组指针(该类型与由框架读取用户所需要的配置项相关);
ACL_MASTER_SERVER_PRE_INIT--该类型表明后面的参数为一函数指针,服务进程启动后会自动切换成普通用户身份,该类型所代表的函数会在服务切换成普通用户身份前进行调用;
ACL_MASTER_SERVER_POST_INIT--该类型表明后面的参数为一函数指针,当服务框架将该服务工作进程切换成普通用户身份后所调用的函数;
ACL_MASTER_SERVER_PRE_ACCEPT--该类型表明后面的参数为一函数指针,当服务框架监听到监听套接口上有新的客户端连接到达,在用户 accept()接受该连接之前可以先回调用户的注册函数,此函数指针即为该回调函数;
ACL_MASTER_SERVER_EXIT--该类型表明后面的参数为一函数指针,当该服务进程退出所回调的用户的注册函数。
2.2)源文件展示
/* main.c */ #include "lib_acl.h" #include "app_log.h" #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> static char *var_cfg_single_banner; static int var_cfg_single_timeout; static ACL_CONFIG_INT_TABLE __conf_int_tab[] = { { "single_timeout", 60, &var_cfg_single_timeout, 0, 0 }, { 0, 0, 0, 0, 0 }, }; static ACL_CONFIG_STR_TABLE __conf_str_tab[] = { { "single_banner", "hello, welcome!", &var_cfg_single_banner }, { 0, 0, 0 }, }; static void __service(ACL_VSTREAM *stream, char *service, char **argv acl_unused) { const char *myname = "__service"; char buf[4096]; int n, ret; /* * Sanity check. This service takes no command-line arguments. */ if (argv[0]) acl_msg_fatal("%s(%d)->%s: unexpected command-line argument: %s", __FILE__, __LINE__, myname, argv[0]); acl_msg_info("%s(%d)->%s: service name = %s, rw_timeout = %d", __FILE__, __LINE__, myname, service, stream->rw_timeout); acl_msg_info("total alloc: %d", acl_mempool_total_allocated()); do { acl_watchdog_pat(); n = acl_vstream_readline(stream, buf, sizeof(buf) - 1); if (n == ACL_VSTREAM_EOF) { acl_msg_info("%s(%d)->%s: read over", __FILE__, __LINE__, myname); break; } ret = acl_vstream_writen(stream, buf, n); if (ret != n) { acl_msg_info("%s(%d)->%s: write error = %s", __FILE__, __LINE__, myname, strerror(errno)); break; } } while (0); } static void __pre_accept(char *name acl_unused, char **argv acl_unused) { } static void __pre_jail_init(char *name acl_unused, char **argv acl_unused) { acl_mempool_open(512000000, 1); /* 是否采用 libcore 的日志记录 */ #ifdef HAS_LIB_CORE # ifdef USE_LIBCORE_LOG app_set_libcore_log(); # endif #endif } static void __post_jail_init(char *name acl_unused, char **argv acl_unused) { } static void service_exit(char *service acl_unused, char **argv acl_unused) { #ifdef HAS_LIB_CORE # ifdef USE_LIBCORE_LOG app_libcore_log_end(); # endif #endif } int main(int argc, char *argv[]) { acl_single_server_main(argc, argv, __service, ACL_MASTER_SERVER_INT_TABLE, __conf_int_tab, ACL_MASTER_SERVER_STR_TABLE, __conf_str_tab, ACL_MASTER_SERVER_PRE_INIT, __pre_jail_init, ACL_MASTER_SERVER_PRE_ACCEPT, __pre_accept, ACL_MASTER_SERVER_POST_INIT, __post_jail_init, ACL_MASTER_SERVER_EXIT, service_exit, 0); exit (0); }
2.3) 配置文件:single_echo.cf
service single
{
# 进程是否禁止运行
master_disable = no
# 服务地址及端口号
master_service = :5003
# 服务监听为域套接口
# master_service = single_echo.sock
# 服务类型
master_type = inet
# master_type = unix
# 是否只允许私有访问, 如果为 y, 则域套接口创建在 {install_path}/var/log/private/ 目录下,
# 如果为 n, 则域套接口创建在 {install_path}/var/log/public/ 目录下,
master_private = n
master_unpriv = n
# 是否需要 chroot: n -- no, y -- yes
master_chroot = n
# 每隔多长时间触发一次,单位为秒(仅对 trigger 模式有效)
master_wakeup = -
# 最大进程数
master_maxproc = 10
# 进程程序名
master_command = single_echo
# 进程启动参数,只能为: -u [是否允许以某普通用户的身份运行]
# master_args =
# 进程日志记录文件
master_log = {install_path}/var/log/single_echo.log
# 传递给服务子进程的环境变量, 可以通过 getenv("SERVICE_ENV") 获得此值
# master_env = logme:FALSE, priority:E_LOG_INFO, action:E_LOG_PER_DAY, flush:sync_flush, imit_size:512,\
# sync_action:E_LOG_SEM, sem_name:/tmp/single_echo.sem
# 每个进程实例处理连接数的最大次数,超过此值后进程实例主动退出
single_use_limit = 250
# 每个进程实例的空闲超时时间,超过此值后进程实例主动退出
# single_idle_limit = 180
# 记录进程PID的位置(对于多进程实例来说没有意义)
single_pid_dir = {install_path}/var/pid
# 进程运行时所在的路径
single_queue_dir = {install_path}/var
# 读写超时时间, 单位为秒
single_rw_timeout = 1800
# 读缓冲区的缓冲区大小
single_buf_size = 8192
# 进程运行时的用户身份
single_owner = root
# single_in_flow_delay = 1
# single_owner = owner
# 用 select 进行循环时的时间间隔
# 单位为秒
# single_delay_sec = 1
# 单位为微秒
# single_delay_usec = 5000
# single_daemon_timeout = 1800
}
2.4)编译源文件
生成 single_echo 可执行程序
make
2.5)拷贝文件
将 single_echo 拷贝至 acl_project/dist/master/libexec/linux32 (假设操作系统是LINUX 32位平台的) 目录,将 single_echo.cf 拷贝至acl_project/dist/master/conf/service/ 目录,从而将 single_echo 置于 acl_master 守护管理进程的控制范围内。
2.6) 安装
cd acl_project/dist/master; chmod 755 setup.sh; ./setup.sh /opt/acl
2.7)启动框架管理控制进程(acl_master)
/opt/acl/sh/start.sh
2.8)手工测试
telnet 127.0.0.1 5003
看是否正常连接服务器,如果连接成功,则随意输入一些字符然后按回车发送,看服务器是否将所发送的数据回显给发送者;如果连接不成功或服务器未正常回显,请查看日志文件:/opt/acl/var/log/single_echo,并找出出错原因。
个人微博:http://weibo.com/zsxxsz
下载:http://sourceforge.net/projects/acl/
svn:svn checkout svn://svn.code.sf.net/p/acl/code/trunk acl-code
github:https://github.com/acl-dev/acl/
QQ 群:242722074
国内镜像:http://git.oschina.net/zsxxsz/acl
相关推荐
§1.1.1 关系模型 23 §1.1.2 Codd十二法则 24 §1.2 关系数据库系统(RDBMS)的组成 24 §1.2.1 RDBMS 内核 24 §1.2.2 数据字典概念 25 §1.3 SQL、SQL*Plus及 PL/SQL 25 §1.3.1 SQL和SQL*PLUS的差别 25 §1.3.2 ...
内容概要:本文档详细介绍了Anaconda的安装、环境管理和包管理的方法。Anaconda是一个强大的Python数据科学平台,提供了包管理器和环境管理器。安装部分包括了从官网或国内镜像源下载并安装Anaconda,安装时建议修改安装路径并勾选添加环境变量。环境管理方面,涵盖了创建、激活、退出、查看和删除虚拟环境的具体命令。包管理则讲解了在虚拟环境中安装、卸载以及查看已安装包的操作。此外,还提供了配置国内镜像源以提高下载速度的方法,以及一些常用命令与技巧,如更新所有包、导出环境和从配置文件创建环境等。; 适合人群:对Python数据科学感兴趣的初学者,以及需要使用Anaconda进行环境和包管理的开发者。; 使用场景及目标:①帮助用户快速完成Anaconda的安装;②让用户掌握虚拟环境的创建与管理,确保不同项目之间的依赖隔离;③使用户能够熟练地进行包的安装、卸载和更新操作;④提高用户在国内网络环境下获取资源的速度。; 阅读建议:阅读时可结合自身需求重点学习环境管理和包管理的相关命令,对于配置镜像源的内容,可根据自己的网络情况选择是否配置。
基于visualstudio2010,包括所有源代码,可以运行, 编程实现直线的 DDA 算法及 Bresenham 算法绘制任意斜率的直线。 设计一个图形并调用 1 中的 Bresenham 算法程序绘制。
内容概要:本文详细介绍了RRT(快速随机树)和RRT*算法在3D场景下的应用,重点在于如何绕过两个圆柱障碍物到达目标点。文中通过MATLAB代码实现了路径规划的具体步骤,包括初始化参数、随机采样、寻找最近节点、扩展树结构、判断是否绕过障碍物以及输出路径图和路径点与障碍物最小距离变化图。此外,还对算法进行了简要介绍,指出了其优点和局限性。 适合人群:从事机器人技术、自动化控制、机械臂路径规划的研究人员和技术人员,尤其是对3D空间避障与路径规划感兴趣的开发者。 使用场景及目标:①帮助研究人员理解和实现RRT和RRT*算法在3D环境中的具体应用;②为移动机器人和机械臂的路径规划提供理论支持和实践指导;③通过图示和代码示例,使读者能够更好地掌握算法的实现细节。 其他说明:虽然RRT和RRT*算法在处理复杂环境下的路径规划问题时表现出色,但也存在一些局限性,如可能陷入局部最优解等问题。未来可以通过改进算法来提升其性能和适用性。
科普内容创作者科普文章AI写作提示词科普论文写作提示词(AI提示词Prompt)
一种新型具有多陷波特性的超宽带天线.zip
cmd-bat-批处理-脚本-vcvars32.zip
内容概要:本文介绍了一种专为六节电池串联设计的模块化SOC主动均衡模型。该模型采用底层双向反激变换器和顶层buck-boost均衡的双重策略,旨在解决电池组中各节电池SOC不一致的问题。通过模块化设计,模型实现了灵活性和扩展性,适用于不同类型的电池组。文章详细介绍了模型的工作原理、设计思路以及仿真实验结果,验证了模型的有效性。 适合人群:从事电池管理系统的研发人员、电力电子工程师、科研工作者。 使用场景及目标:①研究电池组充放电均衡技术;②优化电池管理系统的设计;③作为论文创新和仿真实验的基础。 阅读建议:重点理解双向反激变换器和buck-boost均衡的具体实现方法及其协同工作的机制,结合仿真实验数据进一步验证模型效果。
cmd-bat-批处理-脚本-LaunchDevCmd.zip
数字钟实验24小时制bit文件
2025年系统集成项目管理工程师考试大纲及培训指南2.doc
校园网络课程设计
该数据集收录了1995-2022年期间中国网络媒体与报刊媒体关注度及媒体监督相关的实证研究数据,适用于社会科学与经济管理领域研究。数据内容包含以下三方面指标: 媒体关注度指标:包括标题及内容中出现特定主体的新闻总数,按正、中、负面情感分类统计,并区分原创与非原创内容。例如,标题提及主体的新闻总量、内容提及主体的新闻总量,以及正面/中性/负面新闻的原创数量。 媒体监督指标:采用Janis-Fadner系数(J-F系数)量化媒体监督力度,基于媒体报道的正面与负面内容比例计算,反映媒体对企业、事件或话题的舆论监督强度。 数据类型与结构:提供原始数据、参考文献、统计代码(Do文件)及处理后的结构化数据,覆盖时间跨度达28年。数据来源于公开新闻报道及第三方平台监测,涵盖网络媒体(如门户网站、社交媒体)与报刊媒体的多维信息。 该数据集可用于分析媒体舆论对经济主体行为的影响、风险抑制机制研究(如企业违规行为与媒体曝光的关联性)、舆情传播特征与社会治理等领域,为实证研究提供基础数据支持。数据格式兼容主流统计软件,便于直接应用于计量模型分析。
cmd-bat-批处理-脚本-showWLAN.zip
@吾乃周树人中人 【自制】STM32无刷电机FOC驱动一体板---无刷电机能放歌?【FOC三环控制】 (https://www.bilibili.com/video/BV17FUeYQEXa/?spm_id_from=333.1387.favlist.content.click&vd_source=b344881caf56010b57ef7c87acf3ec92) 这是一块集成驱动、控制、CAN通信、磁编码器、还有电流检测的无刷电机驱动板 功能1:低速高扭矩模式 功能2:双电机同步模式 功能3:力反馈模式 功能4:速度环+位置环模式 功能5:速度环+电流环模式 功能6:指尖陀螺模式 功能7:指尖陀螺plus模式 功能8:阻尼旋钮模式 功能9:多档开关模式 功能10:播放音乐 主控:STM32F103C8T6 使用Hal库 磁编码芯片:AS5600 IIC通信 电流检测芯片:两路 INA240 模拟量输入 can芯片:TJA1050 有感电机:需要在电机轴上固定径向磁铁 供电电压:12V
NVIDIA深度学习学院(DLI)是一个专注于深度学习、加速计算和人工智能领域的培训与认证平台。通过其丰富的学习资源,学员可以掌握构建、训练和部署神经网络等核心技能。本文将重点介绍NVIDIA DLI深度学习基础课程中的关键知识点,包括深度学习模型的构建、数据预处理等。 模型构建 在代码示例中,使用TensorFlow的Keras模块导入了预训练的VGG16模型作为基础架构。 关键点包括: 使用keras.applications.VGG16加载VGG16模型,其中weights="imagenet"表示使用基于ImageNet数据集的预训练权重;input_shape=(224,224,3)指定了输入图像的尺寸为224×224像素,且为三通道(RGB);include_top=False意味着不包含原始模型的顶层全连接层。 通过base_model.trainable = False冻结基础模型的所有层,确保在后续训练中这些层的权重不会更新。 构建新模型时,创建输入层inputs = keras.Input(shape=(224,224,3)),利用基础模型提取特征x = base_model(inputs, training=False),随后添加全局平均池化层x = keras.layers.GlobalAveragePooling2D()(x),并在最后添加一个具有6个节点的分类层outputs = keras.layers.Dense(6, activation="softmax")(x),适用于多分类任务。 使用model.summary()查看模型的结构细节。 编译模型时,选择交叉熵损失函数loss="categorical_crossentropy"、Adam优化器optimizer="adam"以及准确率metrics=["accuracy"]作为评估指标
基于变值测量模型的心电信号可视化研究.zip
《Java+SQL Server学生成绩管理系统》是一款融合了Java编程语言与SQL Server数据库技术的软件,专为高校或教育机构设计,用于高效管理学生的考试成绩。它具备数据录入、查询、统计分析等功能,旨在提升教学管理效率。 该系统的核心技术包括:一是Java后端开发。Java承担后端任务,处理HTTP请求、实现业务逻辑以及与数据库交互。项目可能借助Spring框架,利用其依赖注入、AOP等特性,简化开发流程。Spring MVC则助力实现MVC模式,处理Web请求。二是JSP技术。JSP是一种动态网页技术,页面融合HTML、CSS、JavaScript和Java代码,用于呈现用户界面及处理前端简单逻辑。三是SQL Server数据库。作为数据存储后端,SQL Server支持通过SQL语句完成表的创建、数据的增删改查等操作,还可借助存储过程和触发器提升功能与安全性。四是数据库设计。系统数据库设计关键,包含“学生”“课程”“成绩”等表,通过主外键关联数据,如“学生”表与“成绩”表通过学生ID关联,“课程”表与“成绩”表通过课程ID关联。五是B/S架构。采用浏览器/服务器架构,用户经Web浏览器访问系统,计算与数据处理在服务器端完成,降低客户端硬件要求。六是安全性。系统设置身份验证与授权机制,如登录验证,确保信息访问安全。同时,为防范SQL注入等威胁,采用预编译语句或ORM框架处理SQL命令。七是异常处理。Java的异常处理机制可捕获运行时问题,保障系统稳定性与用户体验。八是报表统计功能。系统具备成绩统计功能,如计算平均分、排名、及格率等,常使用聚合函数(SUM、AVG、COUNT等)和GROUP BY语句。九是设计模式。开发中可能运用单例模式、工厂模式等,提升代码可维护性和复用性。十是版本控制。项目可能使用Git等版本控制系统,便于团队协作与代码管理。 该学生成绩管理
cmd-bat-批处理-脚本-semver.zip
cmd-bat-批处理-脚本-rems.zip