tiny-process-library:一个用 C++ 编写的轻量级、跨平台(支持 Windows、Linux、macOS)的进程管理库

目录

1.简介

2.安装与集成

3.核心使用示例

4.跨平台注意事项

5.常见问题解决

6.总结


1.简介

如果你在C++项目里需要调用另一个程序------比如用FFmpeg转码视频、用ImageMagick处理图片,或者启动一个Python脚本------肯定经历过跨平台进程调用的痛苦。Windows的CreateProcess和Unix的fork/exec完全两套API,还要处理管道、等待、错误码......光是让程序在不同系统上都能运行就得写一堆条件编译。

这时候,tiny-process-library 就像给你配了个万能的"程序启动管家"。它是一个单头文件的C++库,专门解决一件事:用统一的API在Windows、Linux、macOS上启动和管理外部进程,而且代码量极小,集成起来毫无负担。

它的特点有:

  • 接口简洁,易于使用
  • 支持同步 / 异步执行外部命令
  • 支持捕获子进程的 stdout/stderr 输出
  • 支持设置子进程的工作目录
  • 支持终止子进程

2.安装与集成

1.手动集成(推荐新手)

https://gitee.com/ipaihongjun/tiny-process-library.git

  • 将源码中的 process.hppprocess.cpp(Windows 还需 process_win.cpp,Linux/macOS 需 process_unix.cpp)复制到你的项目目录
  • 直接包含头文件即可使用

2.源码编译成库集成

cpp 复制代码
git clone http://gitlab.com/eidheim/tiny-process-library
cd tiny-process-library
mkdir build
cd build
cmake ..
make
./examples

3.CMake集成

如果你的项目使用 CMake,可以通过 add_subdirectory 集成:

cpp 复制代码
# 添加库目录
add_subdirectory(tiny-process-library)
# 链接库
target_link_libraries(你的项目名 tiny-process-library)

3.核心使用示例

1.基础同步执行(阻塞等待进程结束)

执行一个简单命令,等待执行完成并获取退出码:

cpp 复制代码
#include "process.hpp"
#include <iostream>

int main() {
    // 执行命令:Windows 用 "cmd /c echo hello",Linux/macOS 用 "echo hello"
#ifdef _WIN32
    TinyProcessLib::Process process("cmd /c echo hello world", ".");
#else
    TinyProcessLib::Process process("echo hello world", ".");
#endif

    // 阻塞等待进程结束,获取退出码
    int exit_code = process.get_exit_status();
    std::cout << "进程退出码: " << exit_code << std::endl;

    return 0;
}
  • Process 构造函数第一个参数是要执行的命令,第二个是工作目录(. 表示当前目录)
  • get_exit_status() 是阻塞函数,会等待进程执行完成后返回退出码(0 表示成功)

2.异步执行 + 捕获输出(最常用)

异步执行命令,实时捕获 stdout/stderr 输出,不阻塞主线程:

cpp 复制代码
#include "process.hpp"
#include <iostream>
#include <string>

int main() {
    // 存储输出的变量
    std::string output, error;

#ifdef _WIN32
    // Windows 执行 dir 命令
    TinyProcessLib::Process process(
        "cmd /c dir",
        ".",
        [&output](const char* data, size_t size) {  // stdout 回调
            output.append(data, size);
        },
        [&error](const char* data, size_t size) {   // stderr 回调
            error.append(data, size);
        }
    );
#else
    // Linux/macOS 执行 ls -l 命令
    TinyProcessLib::Process process(
        "ls -l",
        ".",
        [&output](const char* data, size_t size) {  // stdout 回调
            output.append(data, size);
        },
        [&error](const char* data, size_t size) {   // stderr 回调
            error.append(data, size);
        }
    );
#endif

    // 异步等待(非阻塞,也可以用 wait() 阻塞)
    while (!process.try_get_exit_status()) {
        // 主线程可以做其他事情
        std::cout << "进程还在运行..." << std::endl;
        // 休眠 500ms,避免循环过快
#ifdef _WIN32
        Sleep(500);
#else
        usleep(500000);
#endif
    }

    // 输出结果
    std::cout << "=== 标准输出 ===" << std::endl;
    std::cout << output << std::endl;
    std::cout << "=== 错误输出 ===" << std::endl;
    std::cout << error << std::endl;

    return 0;
}
  • 第三个参数是 stdout 回调函数,子进程输出时会触发,参数是输出数据和长度
  • 第四个参数是 stderr 回调函数,捕获错误输出
  • try_get_exit_status() 是非阻塞检查进程是否结束,返回 true 表示进程已结束
  • 回调函数是在子线程中执行的,注意线程安全(比如多线程操作同一个变量时加锁)

3.终止子进程

主动终止正在运行的子进程:

cpp 复制代码
#include "process.hpp"
#include <iostream>
#include <chrono>
#include <thread>

int main() {
#ifdef _WIN32
    TinyProcessLib::Process process("cmd /c ping -n 10 127.0.0.1", ".");
#else
    TinyProcessLib::Process process("ping -c 10 127.0.0.1", ".");
#endif

    // 运行 3 秒后终止进程
    std::this_thread::sleep_for(std::chrono::seconds(3));
    std::cout << "终止子进程..." << std::endl;
    process.kill();  // 终止进程

    // 等待进程完全退出
    int exit_code = process.get_exit_status();
    std::cout << "进程退出码: " << exit_code << std::endl;

    return 0;
}
  • kill() 方法会强制终止子进程(Windows 下调用 TerminateProcess,Linux/macOS 下发送 SIGKILL
  • 终止后仍需调用 get_exit_status() 释放资源

4.设置环境变量

给子进程设置自定义环境变量:

cpp 复制代码
#include "process.hpp"
#include <iostream>
#include <vector>
#include <string>

int main() {
    // 构造环境变量列表(格式:KEY=VALUE)
    std::vector<std::string> env = {"MY_VAR=hello_tiny_process", "PATH=/usr/bin"};

#ifdef _WIN32
    TinyProcessLib::Process process(
        "cmd /c echo %MY_VAR%",  // Windows 读取环境变量
        ".",
        [](const char* data, size_t size) {
            std::cout << "输出: " << std::string(data, size) << std::endl;
        },
        nullptr,
        env  // 传入自定义环境变量
    );
#else
    TinyProcessLib::Process process(
        "echo $MY_VAR",  // Linux/macOS 读取环境变量
        ".",
        [](const char* data, size_t size) {
            std::cout << "输出: " << std::string(data, size) << std::endl;
        },
        nullptr,
        env  // 传入自定义环境变量
    );
#endif

    process.get_exit_status();
    return 0;
}

4.跨平台注意事项

  • 命令格式差异
    • Windows 下执行普通命令需要通过 cmd /c 命令(比如 cmd /c dir
    • Linux/macOS 下直接执行命令(比如 ls -l
  • 路径分隔符 :Windows 用 \,Linux/macOS 用 /,建议用 std::filesystem 处理路径
  • 编码问题:Windows 下默认是 GBK 编码,Linux/macOS 是 UTF-8,捕获输出时注意编码转换

5.常见问题解决

  • 进程创建失败
    • 检查命令是否存在(比如 Windows 下有没有 ping.exe
    • 检查工作目录是否存在
  • 输出乱码(Windows)
    • 将命令输出转为 UTF-8,比如 cmd /c chcp 65001 && dir(65001 是 UTF-8 代码页)
  • 回调函数不执行
    • 确保进程有输出,且没有提前终止进程
    • 回调函数是异步的,主线程不要过早退出

6.总结

  • tiny-process-library 核心是 Process 类,支持同步 / 异步执行命令、捕获输出、终止进程,跨平台使用需注意命令格式差异。
  • 异步执行时通过回调函数捕获 stdout/stderr,注意线程安全;同步执行用 get_exit_status() 阻塞等待。
  • 跨平台开发时,用条件编译区分 Windows/Linux/macOS 的命令和路径格式,避免兼容性问题。
相关推荐
学不完的1 小时前
Nginx
linux·运维·nginx·运维开发
汇智信科1 小时前
汇智信科网络考试系统:以技术赋能,重构在线测评新范式
linux·数据库·mysql·oracle·sqlserver·java技术
码农编程录1 小时前
【notes14】debugfs
linux
数据与人1 小时前
Linux中Too many open files错误的解决
linux·服务器·前端
Joren的学习记录1 小时前
【Linux运维大神系列】k8s项目部署实战
linux·运维·kubernetes
杰克崔1 小时前
android的lmkd的实现及代码分析
android·linux·运维·服务器·车载系统
Codefengfeng1 小时前
webshell流量分析-Practice1
linux·web安全
BullSmall1 小时前
从2026年春晚 详细分析未来IT行业的发展
linux·运维·服务器·数据库
安谦柔1 小时前
Windows系统电脑无法通过USB连接网络的解决方案
网络·windows