C++笔记之popen()和std_system()和std_async()执行系统命令比较

news2024/11/25 10:35:26

C++笔记之popen()和std_system()和std_async()执行系统命令比较

code review!

文章目录

  • C++笔记之popen()和std_system()和std_async()执行系统命令比较
    • 1.popen()
    • 2.std::system()
    • 3.std::async()——C++11提供的异步操作库,适合在多线程中执行外部命令,建议使用!
      • std::async和std::future
    • 4.system()和std::async结合使用
    • 5.popen()和std::async结合使用

1.popen()

在这里插入图片描述

代码

#include <iostream>
#include <stdio.h>

int main() {
  FILE* pipe = popen("ls -l", "r");
  if (!pipe) {
    std::cerr << "Error: popen() failed!" << std::endl;
    return 1;
  }
  char buffer[128];
  while (fgets(buffer, 128, pipe) != NULL) {
    std::cout << buffer;
  }
  pclose(pipe);
  return 0;
}

2.std::system()

在这里插入图片描述

代码

#include <iostream>
#include <cstdlib>

int main() {
  int result = std::system("ls -l");
  if (result != 0) {
    std::cerr << "Error: std::system() failed!" << std::endl;
    return 1;
  }
  return 0;
}

在这里插入图片描述

3.std::async()——C++11提供的异步操作库,适合在多线程中执行外部命令,建议使用!

在这里插入图片描述

在这里插入图片描述

代码

#include <iostream>
#include <future>
#include <string>

std::string execute_command(const std::string& cmd) {
  std::array<char, 128> buffer;
  std::string result;
  std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
  if (!pipe) {
    throw std::runtime_error("popen() failed!");
  }
  while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
    result += buffer.data();
  }
  return result;
}

int main() {
  auto future_result = std::async(std::launch::async, execute_command, "ls -l");
  std::cout << future_result.get() << std::endl;
  return 0;
}

上面的代码会在新的线程中异步执行"ls -l"命令,并将输出结果存储在一个字符串中。通过std::async和std::future的组合,可以轻松地在多线程环境中执行外部命令,避免了阻塞主线程的问题。

std::async和std::future

在这里插入图片描述

4.system()和std::async结合使用

在这里插入图片描述

void Node::clicked_a_button(int var) {
    auto fut1 = std::async(std::launch::async, []() {
        system("/home/user/xxx.sh arg1 arg2");
        // or
        // system("rm -r *.txt");
    });

    fut1.wait();
}

这段代码是一个C++函数,涉及到多线程编程和系统调用。让我们逐行分析:

  1. void Node::clicked_a_button(int var) 是一个成员函数,可能属于一个类(Node),接受一个整数参数 var

  2. auto fut1 = std::async(std::launch::async, []() { ... }); 创建了一个异步任务(使用std::async)并将其分配给名为 fut1std::future对象。这个异步任务使用 std::launch::async 策略,表示它应该在一个新的线程中异步执行。

  3. system("/home/user/xxx.sh arg1 arg2"); 这是一个系统调用,用于执行外部的shell脚本(xxx.sh)并传递两个参数(arg1arg2)。这个命令将在一个新的子进程中运行,通常用于执行外部命令。

  4. fut1.wait(); 这一行等待异步任务(在fut1中)的完成。这会导致主线程阻塞,直到异步任务执行完毕。

需要注意的是,虽然std::async用于启动异步任务,但在此代码中,主线程仍然会等待异步任务完成,因为在 fut1.wait(); 处进行了显式等待。这意味着异步任务的效果仅在执行系统调用期间是异步的,而在 fut1.wait(); 处,主线程将被阻塞,直到系统调用完成。

这种用法可以用于在C++中启动外部进程或shell脚本,但需要小心,因为system函数在执行时会阻塞主线程,可能导致整个应用程序在执行外部命令时暂停。如果需要更多的并发性,可以考虑使用std::thread或其他多线程库来在后台执行系统调用,以便主线程可以继续执行其他任务。

5.popen()和std::async结合使用

  • 1.执行外部shell脚本并传递参数的简单例程
    在C++中,您可以使用popen函数来执行外部Shell脚本,并使用std::async来异步执行它。下面是一个简单的例程,演示如何结合使用这两个功能来执行外部Shell脚本并传递参数。
#include <iostream>
#include <fstream>
#include <future>
#include <string>

int executeShellScript(const std::string& scriptPath, const std::string& argument) {
    std::string command = scriptPath + " " + argument;
    FILE* pipe = popen(command.c_str(), "r");
    if (!pipe) {
        std::cerr << "Error executing the shell script." << std::endl;
        return -1;
    }

    char buffer[128];
    std::string result = "";

    while (!feof(pipe)) {
        if (fgets(buffer, 128, pipe) != nullptr) {
            result += buffer;
        }
    }

    int exitCode = pclose(pipe);
    if (exitCode == -1) {
        std::cerr << "Error closing the pipe." << std::endl;
        return -1;
    }

    std::cout << "Shell script output: " << result;
    return exitCode;
}

int main() {
    std::string scriptPath = "your_script.sh";
    std::string argument = "your_argument";

    std::future<int> result = std::async(std::launch::async, executeShellScript, scriptPath, argument);

    // You can perform other tasks while the script is running asynchronously

    int exitCode = result.get();
    std::cout << "Shell script exited with code: " << exitCode << std::endl;

    return 0;
}

在上面的示例中,executeShellScript 函数接受Shell脚本的路径和要传递给脚本的参数。它使用 popen 执行脚本,并在异步任务中调用它。在 main 函数中,std::async 用于启动异步任务执行外部脚本。您可以在启动异步任务后执行其他任务,然后使用 result.get() 来等待异步任务的完成并获取返回的退出码。

请替换 "your_script.sh""your_argument" 为实际的脚本路径和参数。确保您的脚本在执行时可以接受参数并处理它们。

  • 2.执行linux系统命令的简单例程
    在C++中,您可以结合使用popen函数和std::async来执行Linux系统命令。下面是一个简单的例程,演示如何执行Linux系统命令并获取其输出。
#include <iostream>
#include <fstream>
#include <future>
#include <string>

std::string executeLinuxCommand(const std::string& command) {
    FILE* pipe = popen(command.c_str(), "r");
    if (!pipe) {
        std::cerr << "Error executing the command." << std::endl;
        return "";
    }

    char buffer[128];
    std::string result = "";

    while (!feof(pipe)) {
        if (fgets(buffer, 128, pipe) != nullptr) {
            result += buffer;
        }
    }

    int status = pclose(pipe);
    if (status == -1) {
        std::cerr << "Error closing the pipe." << std::endl;
        return "";
    }

    return result;
}

int main() {
    std::string command = "ls -l"; // Replace with the desired Linux command

    std::future<std::string> result = std::async(std::launch::async, executeLinuxCommand, command);

    // You can perform other tasks while the command is running asynchronously

    std::string commandOutput = result.get();
    std::cout << "Command output:\n" << commandOutput;

    return 0;
}

在上面的示例中,executeLinuxCommand 函数接受要执行的Linux命令,并使用 popen 执行该命令。然后,通过 std::async 在异步任务中调用它。在 main 函数中,std::async 用于启动异步任务执行Linux命令。您可以在启动异步任务后执行其他任务,然后使用 result.get() 来等待异步任务的完成并获取命令的输出。

请替换"ls -l"为您要执行的实际Linux命令。这个示例只是一个演示,您可以根据需要替换命令。确保您的Linux命令能够在Shell中正常执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1091580.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机毕业设计选什么题目好?springboot 美食推荐系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

【翻译】Efficient Data Loader for Fast Sampling-Based GNN Training on Large Graphs

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 此内容为机器翻译的结果&#xff0c;若有异议的地方&#xff0c;建议查看原文。 机器翻译的一些注意点&#xff0c;比如&#xff1a; 纪元、时代 > epoch工人 > worker火车、培训、训练师 > train Effic…

Codeforces Round 903 (Div. 3)

D. Divide and Equalize Example input Copy 7 5 100 2 50 10 1 3 1 1 1 4 8 2 4 2 4 30 50 27 20 2 75 40 2 4 4 3 2 3 1 output Copy YES YES NO YES NO YES NONote The first test case is explained in the problem statement. 很重要很重要的知识点&a…

如何使用JMeter测试导入接口/导出接口

今天一上班&#xff0c;被开发问了一个问题&#xff1a;JMeter调试接口&#xff0c;文件导入接口怎么老是不通&#xff1f;还有导出文件接口&#xff0c;不知道文件导到哪里去了&#xff1f; 我一听&#xff0c;这不是JMeter做接口测试经常遇到的嘛&#xff0c;但是一时半会又…

【爬虫实战】用pyhon爬百度故事会专栏

一.爬虫需求 获取对应所有专栏数据&#xff1b;自动实现分页&#xff1b;多线程爬取&#xff1b;批量多账号爬取&#xff1b;保存到mysql、csv&#xff08;本案例以mysql为例&#xff09;&#xff1b;保存数据时已存在就更新&#xff0c;无数据就添加&#xff1b; 二.最终效果…

PLC和工控机的网络特性

现场总线技术是工业自动化***深刻变革之一。PLC和工控机采用现场总线后可方便地作为I/O站和监控站连接在DCS系统中。现场总线是一种取代4&#xff5e;20mA标准&#xff0c;用于连接智能现场设备和控制设备的双向数字通讯技术&#xff0c;现场总线具有开放性和互操作性&#xff…

MongoDB 集群配置

一、副本集 Replica Sets 1.1 简介 MongoDB 中的副本集&#xff08;Replica Set&#xff09;是一组维护相同数据集的 mongod 服务。 副本集可提供冗余和高可用性&#xff0c;是所有生产部署的基础。 也可以说&#xff0c;副本集类似于有自动故障恢复功能的主从集群。通俗的讲就…

视觉里程计- 位姿

SLAM中的位姿概念对新手很难&#xff0c;这里讨论下。首先放出一张图&#xff0c;下文会反复说道这张图。 注意到位姿节点之间的变换并不是位姿&#xff0c;之前一直有误解&#xff1b;一般地有如下概念&#xff1a; 路标节点&#xff1a;也就是观测方程【数学形式下见】的观测…

运算放大器基本原理与参数解读-优先看

运算放大器基本原理与参数解读 运算放大器的出现&#xff0c;大大降低了硬件模拟前端电路设计的难度。但是对于高精度的模拟信号处理电路中&#xff0c;用好运放也不是一件容易的事&#xff0c;更不用说压着最低的物料成本设计出符合系统要求的运放电路了。高端的电路往往蕴含着…

第二证券:跨行转账为什么迟迟不到账?

现在&#xff0c;越来越多的人挑选使用跨行转账来结束日常资金生意。不过&#xff0c;有时候在进行跨行转账时&#xff0c;或许会出现迟迟不到账的状况。这种状况常常让人感到困惑和焦虑。所以&#xff0c;我们需求深入分析这个问题&#xff0c;找出原因&#xff0c;以便可以防…

光伏PV三相并网逆变器MATLAB/Simulink仿真分析

微❤关注“电击小子程高兴的MATLAB小屋”获得资料&#xff08;专享优惠&#xff09; 光伏PV三相并网逆变器Matlab/Simulink仿真 光伏PV三相并网逆变器MATLABf仿真下载 引言&#xff1a; 随着可再生能源的日益重视和发展&#xff0c;光伏发电系统在电力系统中的地位越来越重…

C/C++笔试易错题+图解知识点(二)—— C++部分(持续跟新中)

目录 1.构造函数初始化列表 1.1 构造函数初始化列表与函数体内初始化区别 1.2 必须在初始化列表初始化的成员 2. 引用初始化以后不能被改变&#xff0c;指针可以改变所指的对象 1.构造函数初始化列表 有一个类A&#xff0c;其数据成员如下&#xff1a; 则构造函数中&#xff0c…

vue项目打包,使用externals抽离公共的第三方库

封装了一个插件&#xff0c;用来vue打包抽离公共的第三方库&#xff0c;使用unplugin进行插件开发&#xff0c;vite对应的功能使用了vite-plugin-externals进行二次开发 github地址 npm地址 hfex-auto-externals-plugin 自动注入插件,使用 unplugin 和 html-webpack-plugin进…

01 | Spring Data JPA 初识

Spring Boot 和 Spring Data JPA 的 Demo演示 我们利用 JPA Spring Boot 简单做一个 RESTful API 接口&#xff0c;方便你来了解 Spring Data JPA 是干什么用的&#xff0c;具体步骤如下。 第一步&#xff1a;利用 IDEA 和 SpringBoot 2.3.3 快速创建一个案例项目。 点击“…

2.MySQL表的操作

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 表的操作 (1)表的创建 CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎; 存储引擎的不同会导致创建表的文件不同。 换个引擎。 t…

【C语言】结构体、位段、枚举、联合(共用体)

结构体 结构&#xff1a;一些值的集合&#xff0c;这些值称为成员变量。结构体的每个成员可以是不同类型的变量&#xff1b; 结构体声明&#xff1a;struct是结构体关键字&#xff0c;结构体声明不能省略struct&#xff1b; 匿名结构体&#xff1a;只能在声明结构体的时候声…

伦敦银单位转换很简单

伦敦银源自于英国伦敦的电子化的白银投资方式&#xff0c;高杠杆和高收益的它的基本属性&#xff0c;但有别于国内大家所熟悉的投资品种&#xff0c;伦敦银在交易过程中有很多不一样的地方&#xff0c;需要大家地去留意。 比如伦敦银的计价单位是盎司&#xff0c;而且具体来说…

【Qt上位机】打开本地表格文件并获取其中全部数据

前言 其实本文所实现的功能并非博主要实现的全部功能&#xff0c;只是全部功能中的一小部分&#xff0c;这里只是为了记录一下实现方法&#xff0c;防止后续忘记&#xff0c;仅供参考。 文章目录 一、实现效果二、UI设计三、程序设计3.1 选择本地表格文件3.2 获取表格总行列数3…

百度Echarts实现饼图,较官网示例更多项显示

本来是想直接使用官网示例修改几个地方就用起来&#xff0c;但是用户希望一眼就看到百分占比&#xff0c;但是官网示例没有使用lable的&#xff0c;找了半天都没找到&#xff0c;后来通过对比其他饼图发现lable这个项&#xff0c;再次记录一下 首先看效果图&#xff1a; 2. 代码…

国海证券:36氪(KRKR):新经济内容平台龙头,多元变现可期

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;国海证券今日发布了关于36氪的新经济内容平台龙头&#xff0c;多元变现可期研报。国海证券主要内容如下&#xff1a;1、新经济产业发展迅猛&#xff0c;36氪定位为以媒体为旗舰的新经济服务集团&a…