【C++并发】[Popen] C++执行不会自动结束的shell指令,如何管理这些子进程?

demo

比如ros2 topic pub就是一个可能不会自动结束的shell指令,在C++进行并发设计时,往往可能导致这些进程变成野进程

因此我们需要主动管理 / 退出他们

以下给出一个 基于 **close(pipe)**强行注销管道 以实现关闭进程的方法。



#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <thread>
#include <sstream>

std::string command = R"(
ros2 topic pub /initialpose geometry_msgs/PoseWithCovarianceStamped "\
header:
    stamp:
        sec: 0,
        nanosec: 0
    frame_id: 'map'
pose:
    pose:
        position: 
            x: -2.0,
            y: -0.5,
            z: 0.0
        orientation:
            x: 0.0, 
            y: 0.0, 
            z: 0.01, 
            w: 1.0
    covariance: [0.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.06853891909122467]
" -1 
)";
std::string command_1 = "ros2 topic echo /scan --full-length --once > ls.yaml";

std::vector<std::thread> thread_list;

bool SHUTDOWN_FLAG = false;

std::stringstream do_command(const std::string& command, bool if_stdout_ = false) {
    std::stringstream result; 

    FILE* pipe = popen(command.c_str(), "r");
    if (!pipe) {
        std::cerr << "popen() failed!" << std::endl;
        exit(1);
    }

    char buffer[128];
    while (!feof(pipe)) {
        if (fgets(buffer, 128, pipe) != nullptr){
            if (!if_stdout_) std::cout << buffer;
            result << buffer;
        }
        if (SHUTDOWN_FLAG) break;
    }

    int status = pclose(pipe);
    if (status == -1) {
        std::cerr << "pclose() failed!" << std::endl;
        exit(1);
    }

    return result;
}

inline void shutdown() {
    SHUTDOWN_FLAG = true;
    for (auto& thread : thread_list) {
        if (thread.joinable())
            thread.join();
    }
}

int main() {
    // 启动线程执行命令
    thread_list.emplace_back(do_command, command, false); // 输出命令执行结果

    // wait
    for (int i = 0; i < 5; ++i) {
        std::cout << "Main thread is doing task " << i << std::endl;
        // 在这里添加其他任务代码
        std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟执行任务的耗时
    }

    shutdown();
    return 0;
}

Futhermore

该方法仍有局限性:当面对没有输出反馈的终端指令时,依然会失去作用。

本人目前正在设计一种通用性更强的并发管理模板,满足执行终端指令时的多种需求:主动关闭不会自动结束的shell命令、读取命令反馈、stdout和stderr支持、阻塞和非阻塞状态均兼容等。

完美解决方案已给出

详情请见博客:下一篇博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GoesM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值