【问题标题】:How to run multiple shell command at the same time in linux如何在linux中同时运行多个shell命令
【发布时间】:2017-12-22 23:14:43
【问题描述】:

我正在尝试同时使用 c++ 代码在 ubuntu 中运行多个命令。 我使用system() 调用来运行多个命令,但system() 调用的问题是它一次只调用一个命令,其余命令正在等待中。 下面我写了我的示例代码,这可以帮助你得到我想要做的事情。 最重要的是我想一次运行所有这些命令,而不是一个一个地运行。请帮帮我。

提前致谢。

main()
{   
   string command[3];
   command[0]= "ls -l";
   command[1]="ls";
   command[2]="cat main.cpp";  

   for(int i=0;i<3;i++){
       system(command[i].c_str());
   }   
}

【问题讨论】:

  • 在任何你正在学习 UNIX 上的 C++ 的书籍/等中,找到关于 fork() 的部分。
  • (更具体地说,关于fork()exec() 以及一般的流程管理。
  • 你可以使用int main(){return 0;} 你没有检查system 的返回值,所以你不关心你运行的命令是否成功。最好不要运行它们。

标签: c++ linux shell


【解决方案1】:

您应该阅读Advanced Linux Programming(有点旧,但免费提供)。您可能想要(以传统方式,就像大多数 shell 一样):

  • 可能捕获SIGCHLD(设置信号处理程序之前fork,见signal(7) & signal-safety(7)...)

  • 调用fork(2) 来创建一个新进程。请务必检查所有 three 案例(失败返回负数 pid_t,子级返回 0 pid_t,父级返回正数 pid_t)。如果您想与该进程通信,请使用pipe(2)(阅读有关pipe(7)...)fork之前。

  • 在子进程中,关闭一些无用的文件描述符,然后运行一些exec函数(或者底层的execve(2))来运行需要的程序(例如/bin/ls

  • 调用(在父级中,可能在获得SIGCHLD 之后)wait(2)waitpid(2) 或相关函数。

这是很常见的。 Advanced Linux Programming的几章解释的比较好。

在你的情况下不需要使用线程。

但是,请注意lscat 的作用可以通过各种系统调用(在syscalls(2)...中列出)来完成,特别是read(2)stat(2)。您甚至可能不需要运行其他进程。另见opendir(3) & readdir(3)

也许(特别是如果您通过多个pipe(7)-s 与几个 进程进行通信)您可能希望使用poll(2)(或较旧的select(2))拥有一些event loop。一些库提供事件循环(尤其是所有 GUI 小部件库)。

【讨论】:

    【解决方案2】:

    您有几个选择(一如既往):

    • 使用线程(C++ 标准库实现很好)生成多个线程,每个线程执行系统调用然后终止。 join 在线程列表中等待它们全部终止。
    • 使用 *NIX fork 命令生成一个新进程,然后在每个子进程中使用 exec 执行所需的命令(参见 here 以了解“将正确的字符串传递给正确的子进程”的示例)。父进程可以使用waitpid 来确定所有子进程何时完成运行,以便继续执行程序。
    • 将“&”附加到您的每个命令,这将告诉 shell 在后台运行每个命令(具体而言,system 将在后台启动进程然后返回,而无需等待结果)。这个没试过,不知道行不行。但是,您不能等待呼叫终止(感谢 PSkocik)。

    只是指出 - 如果您同时运行这 3 个特定命令,您不太可能能够读取输出,因为它们会同时将文本打印到终端。

    如果您确实需要从程序中读取输出(尽管您的问题中没有提到),this 是相关的(尽管它不使用 system)。

    【讨论】:

    • 最后一项为假。 system("something &amp;"); 将异步创建一个孙子并返回。你一般不能wait 孙子。
    • 我认为fork & waitpid 是最合适的解决方案,而不是线程。
    • 我不同意fork 比线程更混乱。在那种特殊情况下,它会更好(并且 OP 应该使用线程)。
    • 是的,fork,然后是 exec 子级命令,waitwaitpid 父级命令。顺便说一句,在父级中处理 SIGCHLD 信号可能很有用
    • 使用fork()/exec() 分别捕获每个进程的输出是一种成熟的技术。正如我上面评论的那样,阅读书中的一章。
    猜你喜欢
    • 2015-04-02
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 2021-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多