You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言进程管理异常:两次命令调用却执行三次的问题排查

C语言进程创建异常:命令重复执行问题

我正在测试用C语言编写程序创建并管理进程,目标是创建进程并执行两次不同的命令,流程如下:

  • 创建新进程
  • 打印该进程的PID
  • 执行指定命令
  • 进程退出

但遇到了奇怪的问题:执行单个命令时一切正常,但连续执行两次流程时,第二个命令会被执行两次,总共执行了三次命令。

我的代码

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

void launch_command(char command[]) {
  pid_t pid;

  pid = fork();
  if(pid==0)
  {
    printf("Creating process %d from %d\n", getpid(),getppid());
    system(command);
    exit(0);
  }
  else {
    if ((pid = fork()) == -1)
       perror("Error while creating a new process");
  }
}

int main () {
  printf("Root process: %d\n",getpid());

  launch_command("/bin/ls -l");
  while(wait(NULL) >= 0);

  launch_command("/bin/date");
  while(wait(NULL) >= 0);

  return 0;
}

实际输出

$ ./a.out 
Root process: 8924
Creating process 8925 from 8924
Creating process 8928 from 8926
Sun 13 Nov 2022 23:54:51 EST
total 128
-rwxr-xr-x  1 gg  staff  49784 13 Nov 23:54 a.out
-rw-r--r--  1 gg  staff   3499 11 Nov 10:59 create_process.c
Creating process 8931 from 8924
Sun 13 Nov 2022 23:54:51 EST

期望输出

$ ./a.out 
Root process: 8924
Creating process 8925 from 8924
total 128
-rwxr-xr-x  1 gg  staff  49784 13 Nov 23:54 a.out
-rw-r--r--  1 gg  staff   3499 11 Nov 10:59 create_process.c
Creating process 8931 from 8924
Sun 13 Nov 2022 23:54:51 EST

请问这种行为的原因是什么?


问题原因与修复方案

根本原因

问题出在launch_command函数的逻辑里:

  1. 第一次调用fork()后,父进程进入else分支,但你在这个分支里又调用了一次fork(),创建了一个额外的子进程。
  2. 这个额外的子进程没有任何后续处理(既没执行目标命令也没主动退出),它会从fork()的位置继续执行代码,也就是回到main函数的流程中。
  3. 当第一个launch_command执行完,主进程进入wait循环等待所有子进程结束时,这个额外子进程也会执行到wait循环之后,然后调用第二个launch_command("/bin/date")——相当于主进程和这个额外子进程各自执行了一次date命令,所以最终date被执行了两次,加上第一次的ls,总共三次命令执行。

修复后的代码

只需要删除else分支里多余的fork()调用,让每个launch_command只创建一个子进程来执行命令:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

void launch_command(char command[]) {
  pid_t pid;

  pid = fork();
  if(pid == 0)
  {
    printf("Creating process %d from %d\n", getpid(), getppid());
    system(command);
    exit(0);
  }
  else if (pid == -1)
  {
    perror("Error while creating a new process");
  }
}

int main () {
  printf("Root process: %d\n", getpid());

  launch_command("/bin/ls -l");
  while(wait(NULL) >= 0);

  launch_command("/bin/date");
  while(wait(NULL) >= 0);

  return 0;
}

修复后运行,就会得到你期望的输出:只执行一次ls和一次date,没有多余的进程和命令执行。


内容的提问来源于stack exchange,提问作者NIGHTSCROLLER

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 11:31:39