linux系统编程-标题深入理解 fork-execl、system 和 popen:使用方法、参数说明和区别

在 Linux/Unix 环境下,有几种常用的方法可以创建子进程并执行外部命令,其中包括 fork-execl、system 和 popen。本文将深入介绍这三种方法的使用方法、参数说明和区别。

一、fork-execl 方法:

  1. 使用方法:

    • fork:调用 fork 函数创建一个新的子进程。
    • 在子进程中,调用 execl 函数(或其变种函数)来执行指定的外部命令。
    • 子务。进程会调用 execl 函数来执行外部命令,此时父进程不受影响,可以继续执行其他任
    • 虽然子进程正在执行外部命令,但父进程可以通过调用 wait 或 waitpid 等函数来等待子进程的完成,并获取子进程的退出状态。
    • 当父进程调用 wait 函数时,它会阻塞等待子进程的退出状态。父进程会一直等待,直到子进程结束并返回退出状态。这样做的目的是为了确保父进程在子进程完成后再继续执行。

      如果父进程没有调用 wait 函数,而是继续自己的执行流程,那么父进程和子进程将并发执行,互不等待。这可能会导致一些问题,例如父进程结束了但子进程仍在执行,造成子进程成为孤儿进程(即没有父进程管理),或者子进程结束后无法获取其退出状态。

      因此,对于使用 fork-execl 方法创建的子进程,通常建议父进程调用 wait 函数来等待子进程的结束。这样可以确保父进程在子进程完成后再继续执行,并且可以获取到子进程的退出状态,以进行必要的处理。

  2. 参数说明:

    • fork 函数不接受任何参数。
    • execl 函数原型为:int execl(const char *path, const char *arg0, ..., const char *argn, (char *)0);
      • path:命令或可执行文件的路径。
      • arg0 到 argn:外部命令的参数列表。
      • (char *)0:参数列表结束的标志。
  3. 区别:

    • fork-execl 实际上是两个独立的函数调用,fork 负责创建子进程,execl 负责执行外部命令。这种方式需要手动管理子进程的创建和退出,适合在需要更精细控制的场景下使用。
    • execl 函数会直接替换当前进程的镜像,因此在调用 execl 后的代码不会被执行,除非 execl 失败。

二、system 方法:(相当于 fork+execl+wait)

  1. 使用方法:

    • 调用 system 函数来执行指定的外部命令。
    • 当父进程调用 system 函数来执行外部命令时,它会被阻塞,直到子进程执行完毕。
    • 在子进程执行期间,父进程暂停执行其他任务,等待子进程结束。
    • 一旦子进程执行完毕,父进程会恢复执行,可以继续执行其他任务。
  2. 参数说明:

    • system 函数原型为:int system(const char *command);
      • command:要执行的外部命令字符串。
  3. 区别:

    • system 函数将整个命令作为一个字符串参数传递,而不需要手动创建子进程。它会自动创建子进程,执行外部命令,并等待子进程结束。(相当于 fork+execl+wait);
    • system 函数通过创建一个 Shell 进程来解析和执行命令。因此,可以使用 Shell 支持的各种特性和语法,如管道、重定向等。
    • system 函数的返回值为外部命令的退出状态。

三、popen 方法:

  1. 使用方法:

    • 调用 popen 函数来创建一个双向管道并启动一个子进程。
    • 父进程在调用 popen 函数后,可以通过管道与子进程进行双向通信。
    • 父进程可以在子进程执行期间向管道写入数据,供子进程读取。
    • 父进程也可以从管道中读取子进程的输出数据。
    • 父进程可以继续执行其他任务,但需要注意处理与子进程之间的通信
    • 使用 fprintf 或 fwrite 向子进程的标准输入发送数据。
    • 使用 fscanf 或 fread 从子进程的标准输出读取数据。
    • 使用 pclose 关闭管道并等待子进程结束。
  2. 参数说明:

    • popen 函数原型为:FILE *popen(const char *command, const char *type);
      • command:要执行的外部命令字符串。
      • type:管道的读写模式,可以是 "r"(读取模式)或 "w"(写入模式)。
  3. 区别:

    • popen 函数创建了一个双向管道,允许父进程与子进程之间进行双向通信。
    • 父进程通过管道发送数据给子进程,并通过管道接收来自子进程的输出。
    • popen 函数返回一个文件指针,可以像操作普通文件一样使用该文件指针进行输入输出操作。
    • pclose 函数用于关闭管道并等待子进程结束,并返回子进程的退出状态。

总结:

  • fork-execl 是两个独立的函数调用,需要手动管理子进程的创建和退出,适合在需要更精细控制的场景下使用。
  • system 函数通过创建一个 Shell 进程来解析和执行命令,在简单的命令执行场景下使用方便。
  • popen 函数创建双向管道,允许父进程与子进程之间进行双向通信,适合需要与子进程交换数据的场景。

所以实际上,在子进程执行期间,fork-execl 方法允许父进程继续执行其他任务,而 system 方法会暂停父进程的执行。这是两种不同的行为方式。

无论哪种方法,当子进程执行完毕后:

  • 对于 fork-execl 方法,子进程结束后会回到父进程继续执行代码。
  • 对于 system 方法,父进程会在子进程结束后恢复执行。
  • 对于 popen 方法,父进程可以通过调用 pclose 函数来关闭管道并等待子进程的结束。然后父进程继续执行其他任务。

对于只执行外部命令并等待其结束的情况,可以使用 system 函数或 popen 函数来实现。system 函数会阻塞父进程直到子进程执行完毕,而 popen 函数允许父进程与子进程进行双向通信。(popen是阻塞型)

20230816

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值