【问题标题】:Why the program didn't execute some sentences in this C programming or unix programming(execvp() System calls)?为什么程序在这个 C 编程或 unix 编程(execvp() 系统调用)中没有执行某些语句?
【发布时间】:2026-01-01 12:30:01
【问题描述】:

我有以下程序,当我运行程序时,我很困惑为什么我的程序没有执行

   int num=i;
       printf("it is No.%d !",num);
       printf("hello , I will excute execvp!");

我的程序基本上是创建6个子进程来执行executionbode()函数,然后用execvp重载原程序。但是,每次我运行程序时,字符串“你好,我将执行 execvp”从来没有出现过!另外我认为上面那三句话也没有在运行程序中执行?有人能告诉我为什么吗?这是我的程序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include "makeargv.h"
#include "redirection.h"
#include <sys/wait.h>



int executionnode(int i);

int main(){
pid_t childpid;
     int i;
     int row=6;
     for(i=0;i<row;i++)
     {   childpid=fork();
         if(childpid==0)
            continue;
         else if (childpid>0)
            executionnode(i);

         else {
           perror("something wrong");
            exit(1);
          }
      }


}


int executionnode(int i){
   sleep(i);
   printf("hello, I am process:%ld\n",(long)getpid());
   wait(NULL);
   char *execArgs[] = { "echo", "Hello, World!", NULL };
   int num=i;
   printf("it is No.%d !",num);
   printf("hello , I will excute execvp!");
   execvp("echo", execArgs);

}

谁能告诉我为什么?以及如何解决?我觉得真的很奇怪?是因为 execvp() 函数吗?我刚开始学习操作系统,所以我真的很困惑!谢谢你帮助我!

【问题讨论】:

  • 这一行:wait(NULL); 将永远挂起,因为这个孩子没有孩子可以等待。
  • 您似乎对函数的返回值有些困惑:fork()。发布的代码让孩子执行分叉,父母执行execvp() 这与您似乎想要做的相反。
  • 用贴出的代码,会有很多很多的children of children。等等。一般来说,只有父级应该循环,在子级执行 execvp() 时调用 fork()
  • 那里已经回答了完全相同的作者重复,一般来说,一个基本问题之前已经在这个网站上回答了很多次。

标签: linux c system-calls exec


【解决方案1】:

正如 user3629249 所说,您有些困惑。你会得到很多孩子的孩子......等待(NULL)是没用的:)。

我使用这个结构在我的操作系统主题练习中达到了你的目标。

#include <sys/types.h>
#include <unistd.h> 
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#define N 5

int main(int argc, char const *argv[])
{
  pid_t pid,pids[N];
  int i, num_pids = 0;
  int state = 0;
  int prior[]={1,3,5,2,4};

  pid_t parent_pid = getpid();
  printf("Parent pid is %i\n",father_pid);

  // This for loop is the key
  for (i = 0; i < N && getppid() != parent_pid; i++)
  {
    if ((pid = fork()) < 0)
    {
      printf ("fork error\n");
      exit(-1);
    }
    pids[num_pids++] = pid;
  }

  if (pid == 0) // Child processes
  {  
    printf("I am the child %i\n",getpid());
  }
  else // Parent process
  {
    for (i = 0; i < N; i++)
    { 
      int pid_index = prior[i]-1; // Array starts with 0
      pid = waitpid(pids[pid_index]);
      printf("Children %i ended\n",pids[indice_pid]);
      printf("%i alive children\n",N-1-i);
    }
  }

   return 0;
 } 

这种结构之所以有效,是因为您将父进程的 pid 保存在 parent_pid 变量中,并将每个进程的父进程 pid 与 getppid() 进行比较。如果此 pid 与 parent_pid 不同,则此进程是父进程。在另一种情况下,该进程是一个子进程,因此它必须停止(这些进程不必分叉)。通过这种方式,您只能获得所需的叉子。

其余代码相同:Pid==0 为子进程,其他为父进程。你可以在子进程块中调用 executionnode(int i) (记住,pid==0 !!!你有一个错误)。 i 变量在我认为的每个调用中都应该具有正确的值。

祝你好运!

【讨论】: