ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

tiny-process-library 深度解析:FidelityFX SDK 着色器编译器中跨平台子进程管理基石

tiny-process-library 深度解析:FidelityFX SDK 着色器编译器中跨平台子进程管理基石 图形学游戏开发【免费下载链接】dlssg-to-fsr3Adds AMD FSR 3 Frame Generation to games by replacing Nvidia DLSS Frame Generation (nvngx_dlssg).项目地址https://gitcode.com/gh_mirrors/dl/dlssg-to-fsr3点击查看免费下载导读tiny-process-library是一个无外部依赖的轻量级 C 跨平台进程库用于创建、停止子进程并向其 stdin 写入数据、从 stdout/stderr 读取输出。它作为第三方依赖被收纳进本仓库 FidelityFX SDK 的ffx_shader_compilerFidelityFX 着色器编译器即 ffx-sc工具中被实际用于拉起glslangValidator外部编译器进程并异步捕获其编译日志。读完本文你将掌握该库的完整 API、Unix/Windows 双平台实现原理、构建集成方式以及它在 FidelityFX SDK 编译管线中的真实调用场景。一、库的定位FidelityFX SDK 工具链中的进程胶水tiny-process-library的官方 README 将其定位为一个小的平台无关库让 C 中创建和停止新进程变得简单同时支持向新进程的 stdin 写入、从 stdout 和 stderr 读取。该库最初为 C IDE 项目 juCi 开发后被广泛复用。在本仓库中它位于 dependencies/FidelityFX-SDK/sdk/tools/ffx_shader_compiler/libs/tiny-process-library/是 FidelityFX 着色器编译器工具ffx-sc的运行时依赖之一。ffx-sc 负责将 HLSL/GLSL 着色器批量编译为平台二进制并生成反射头文件而其中 GLSL 路径需要调用外部的glslangValidator可执行程序——这正是 tiny-process-library 发挥作用的地方详见后文源码分析。二、核心特性总览README 明确列出的特性如下每一项都能在源码中找到对应实现无外部依赖仅使用标准库thread、mutex、functional等和系统 APICMake 只额外链接线程库见 CMakeLists.txt 中find_package(Threads REQUIRED)。简单易用构造Process对象即启动进程无需手写fork/CreateProcess样板代码。平台无关所有平台均支持通过可执行文件创建进程仅 Unix 系系统额外支持通过函数std::functionvoid()创建进程构造函数带#ifndef _WIN32保护见 process.hpp 第 107-115 行。stdout/stderr 分离读取通过两个匿名回调函数分别消费两个管道的输出底层在 Unix 上用poll()非阻塞轮询process_unix.cpp 的async_read()。支持写入 stdinwrite()方法受互斥锁保护close_stdin()通知子进程参数发送完毕。可终止运行中的进程kill()在 Unix 系系统上支持 SIGTERMforcetrue时与 SIGINT默认。正确关闭文件描述符/句柄Unix 端用close_fds()关闭并join()读线程Windows 端用 RAII 的Handle包装类自动CloseHandle见 process_win.cpp 第 13-34 行。三、API 全面解析Config 与 Process库的全部公开接口集中在单头文件 process.hpp 中位于命名空间TinyProcessLib。3.1 Config 配置结构体Config用于向构造函数传递附加参数包含三个成员成员类型默认值说明buffer_sizestd::size_t131072128 kB读取 stdout/stderr 的缓冲区大小inherit_file_descriptorsboolfalse是否继承父进程的文件描述符Windows 上仅当read_stdoutnullptr、read_stderrnullptr且open_stdinfalse时生效show_windowConfig::ShowWindowshow_default仅 Windows控制进程窗口如何显示对应STARTUPINFO的wShowWindow字段ShowWindow是枚举类取值与 Win32ShowWindow语义一一对应hide、show_normal、show_minimized、maximize/show_maximized、show_no_activate、show、minimize、show_min_no_active、show_na、restore、show_default、force_minimize。3.2 类型别名id_typeWindows 上为unsigned longUnix 上为pid_t进程 ID 类型。fd_typeWindows 上为void*句柄指针Unix 上为int文件描述符类型。string_typeWindows 编译UNICODE时是std::wstring否则是std::stringUnix 恒为std::string。environment_typestd::unordered_mapstring_type, string_type用于自定义子进程环境变量。3.3 构造函数5 个重载所有构造函数均为noexcept并在内部依次执行open(...)启动进程、async_read()启动异步读取线程见 process.cpp 第 5-41 行Process(arguments, path, read_stdout, read_stderr, open_stdin, config)——以参数向量方式启动继承调用进程的环境变量Process(command, path, read_stdout, read_stderr, open_stdin, config)——以整条命令行字符串方式启动继承环境变量与 1、2 相同签名但额外带environment参数的版本——使用指定的环境变量表启动仅 UnixProcess(function, read_stdout, read_stderr, open_stdin, config)——直接以std::functionvoid()作为子进程执行体。各参数含义arguments/command要执行的命令command形式在 Unix 上经/bin/sh -c执行支持管道、重定向等 shell 语法。path子进程的工作目录。Windows 上通过STARTUPINFO配合chdir类逻辑处理Unix 上对参数形式调用chdir(path)对命令形式则构造cd ... command并对单引号做转义以避免符号链接解析问题见 process_unix.cpp 第 165-179 行。read_stdout/read_stderrstd::functionvoid(const char* bytes, size_t n)形式的匿名回调分别接收 stdout/stderr 数据块传nullptr表示不读取对应管道。open_stdin为true时打开 stdin 管道供write()使用。config上文Config结构体。3.4 主要成员方法方法签名行为get_id()id_type get_id() const noexcept返回已启动进程的进程 IDget_exit_status()int get_exit_status() noexcept阻塞等待进程结束并返回退出状态码try_get_exit_status()bool try_get_exit_status(int) noexcept非阻塞探测进程已结束则置退出码并返回true否则返回falsewrite()bool write(const char*, size_t)/bool write(const std::string)写入 stdin未以open_stdintrue构造时抛出std::invalid_argumentclose_stdin()void close_stdin() noexcept关闭 stdin若进程从 stdin 读取参数调用它通知参数已全部发送kill()void kill(bool force false) noexcept终止进程forcetrue仅 Unix 支持发 SIGTERM否则发 SIGINTkill(id, force)static void kill(id_type, bool) noexcept按进程 ID 终止signal()void signal(int signum) noexcept仅 Unix向进程发送任意信号一个值得注意的细节Unix 端kill实际调用::kill(-data.id, ...)即向整个进程组发送信号——子进程在fork后调用了setpgid(0, 0)自成进程组确保信号能覆盖到子进程派生的孙进程process_unix.cpp 第 102、349-357 行。四、双平台实现原理4.1 Unix 端process_unix.cppfork pipe pollUnix 实现围绕fork()展开按需为 stdin/stdout/stderr 创建pipe()fork()出子进程子进程内用dup2()将管道读写端重定向到 0/1/2关闭多余描述符若inherit_file_descriptorsfalse则关闭 3 到min(8192, sysconf(_SC_OPEN_MAX))之间的所有 fd注释说明这是借鉴 Debian 默认_SC_OPEN_MAX的优化setpgid(0,0)脱离父进程进程组对参数形式调用execv/execve对命令形式调用execl(/bin/sh, -c, ...)/execle执行失败则_exit(EXIT_FAILURE)父进程在独立std::thread中通过poll()非阻塞轮询 stdout/stderr 管道fd 设为O_NONBLOCK读取到的数据分发给对应回调直到管道关闭或出错。退出码处理上waitpid得到的状态码若 256会右移 8 位归一化并缓存到data.exit_status以便ECHILD进程已不存在时还能返回历史退出码。4.2 Windows 端process_win.cppCreatePipe CreateProcessWindows 实现基于 Win32 管道与CreateProcess用CreatePipe创建三组管道配合SetHandleInformation精确控制句柄的可继承性通过STARTUPINFO.hStdInput/hStdOutput/hStdError把管道接入子进程必要时置STARTF_USESTDHANDLES若config.show_window ! show_default则额外置STARTF_USESHOWWINDOW并回填wShowWindow所有 HANDLE 由 RAIIHandle包装类自动关闭进程句柄等资源随析构释放全局互斥锁create_process_mutex串行化进程创建规避 Win32 管道继承相关的竞态问题源码注释给出了 Reddit 讨论链接特例MSYS2 环境编译时定义MSYS_PROCESS_USE_SH命令会经过反斜杠与双引号转义后交给sh执行见 process_win.cpp 第 109-120 行以及 CMakeLists.txt 中if(MSYS)分支。注意头文件注释中的平台差异提醒Windows 上无法指定只重定向部分管道因此当read_stdoutnullptr、read_stderrnullptr且open_stdinfalse时stdin/stdout/stderr 会直接继承自父进程。五、构建与集成指南5.1 作为独立项目构建Unix 系README 给出的标准流程git clone http://gitlab.com/eidheim/tiny-process-library cd tiny-process-library mkdir build cd build cmake .. make ./examples示例程序examples.cpp位于库根目录展示了各构造方式的用法。5.2 在 Windows 上用 MSYS2 构建git clone http://gitlab.com/eidheim/tiny-process-library cd tiny-process-library mkdir build cd build cmake -GMSYS Makefiles .. make ./examples其中-GMSYS Makefiles选择 MSYS2 的生成器且此时会自动定义MSYS_PROCESS_USE_SH让命令通过sh执行以兼容 MSYS 环境。5.3 CMake 集成方式其 CMakeLists.txt 的集成设计很清晰add_library(tiny-process-library process.cpp)并导出别名tiny-process-library::tiny-process-library平台源文件自动分流WIN32编译process_win.cpp否则编译process_unix.cppMSVC 下私有定义/D_CRT_SECURE_NO_WARNINGS屏蔽安全警告非 MSVC 下用-stdc11 -Wall -Wextra链接CMAKE_THREAD_LIBS_INIT线程库当它作为独立项目CMAKE_SOURCE_DIR等于自身目录时才构建examples并执行install作为子项目被add_subdirectory引入时则跳过示例与安装——这正是 FidelityFX SDK 的使用方式BUILD_TESTING选项在子项目场景默认关闭。本仓库的 ffx_shader_compiler 正是通过子项目方式接入在其 CMakeLists.txt 第 132 行add_subdirectory(libs/tiny-process-library)并在第 135 行target_link_libraries(... tiny-process-library)完成链接。六、源码级实战ffx-sc 如何用它驱动 glslangValidator这是本库在当前仓库中最具代表性的真实用例。ffx-sc 的 GLSL 编译器组件glsl_compiler.cpp在Compile()中拼接出glslangValidator命令行含-I包含路径、-D宏定义、调试选项-g -gVS -Od和输出-o temp.spv见第 179-219 行定义同一个 lambda 同时作为 stdout 与 stderr 回调第 225-258 行逐行解析输出剥掉ERROR:前缀、从shaderPath:line:前缀中提取出错行号收集为ErrorData向量第 260 行一句代码启动进程并异步读取输出tpl::Process process(cmdLine, , func, func); bool succeeded process.get_exit_status() 0;这里tpl是 pch.hpp 第 53 行的命名空间别名namespace tpl TinyProcessLib;cmdLine是完整命令串工作目录传空字符串两个回调均为同一个日志解析函数。get_exit_status()阻塞等待编译结束并返回退出码 0表示编译成功随后读取临时.spv二进制、计算 MD5 哈希作为排列permutation命名并通过 spirv-reflect 提取资源反射数据第 285-316 行。这一用例完整演示了本库的三步典型用法构造即启动 → 回调异步收日志 → 阻塞取退出码也印证了 README 中stdout 与 stderr 分离异步读取正确关闭文件描述符等特性在真实编译器工具链中的价值——ffx-sc 需要并发编译大量着色器排列绝不能因管道未读而阻塞死锁。七、编码风格约定clang-format 补丁README 末尾说明了该库采用的格式化约定由于 clang-format 对 lambda 的支持不佳项目使用一个打了自定义补丁的 clang-format。补丁作用于lib/Format/ContinuationIndenter.cpp核心改动是bool ContinuationIndenter::canBreak(const LineState State) { if(Style.ColumnLimit0) return true; ... bool ContinuationIndenter::mustBreak(const LineState State) { if(Style.ColumnLimit0) return false; ...即在ColumnLimit0不限列宽时强制允许断行、禁止强制换行避免 lambda 参数列表被列宽规则粗暴截断。对于贡献者而言这提示了格式化时需使用带此补丁的 clang-format 版本或在ColumnLimit: 0下配置.clang-format。八、版本与维护信息库目录内附有维护专用说明 CAULDRONREADME.md记录当前收纳版本为v2.0.4并给出更新流程从上游获取最新发布包 → 解压 → 将根目录所有 cpp/h 文件、CMakeLists、readme、license 拷贝至本目录 → 留意被删除的文件 → 更新本文件中的版本号。这说明它是作为第三方源码整体 vendored 进 SDK 的遵循 MIT 类宽松许可目录内附 LICENSE。结语tiny-process-library以不足千行的体量为 C 项目提供了开箱即用的跨平台子进程管理能力fork/CreateProcess 的细节被封装为一次构造调用stdout/stderr 的异步读取与 stdin 写入由回调与互斥锁优雅承载进程组信号与句柄管理则保证了清理的确定性。在 FidelityFX SDK 的着色器编译器中它稳定支撑了 glslangValidator 的批量驱动与日志解析是理解 ffx-sc 工具链工作原理时不可忽略的一块基石。相关深入阅读库头文件完整 APIUnix 实现 与 Windows 实现实际调用场景ffx-sc GLSL 编译器ffx_shader_compiler 的 CMake 集成赞分享图形学游戏开发【免费下载链接】dlssg-to-fsr3Adds AMD FSR 3 Frame Generation to games by replacing Nvidia DLSS Frame Generation (nvngx_dlssg).项目地址https://gitcode.com/gh_mirrors/dl/dlssg-to-fsr3点击查看免费下载相关推荐探索图形编程新纪元glslcc —— 跨平台着色器编译器探索图形编程新纪元glslcc —— 跨平台着色器编译器 在图形编程领域着色语言如GLSLOpenGL Shading Language起着至关重要的作LYGIA Shader Library你的跨平台着色器开发利器LYGIA Shader Library你的跨平台着色器开发利器 项目介绍 LYGIA Shader Library https://github.com/pnvim-dap-python高级技巧自定义测试运行器与虚拟环境配置指南nvim dap python高级技巧自定义测试运行器与虚拟环境配置指南 nvim dap python是Neovim编辑器中一款强大的Python调试插件上一篇LocalAI实战指南从零搭建企业级本地智能服务平台下一篇终极指南3步解锁免费DeepL翻译神器创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表