为什么在 c 程序中 fork 之后 execv 比 printf 慢?

问题描述

假设我有以下名为 program.c 的程序

#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>


int function(char **argv) {
    pid_t pid = fork();
    if (pid > 0) {
    execv(*argv,argv); 
    }
    
    int value=0;
    return value;
}

int main(int argc,char **argv) {
    int return2;
    
    return2 = function(argv+1);
    printf("%d\n",return2);
}

而我执行./program /bin/ls,为什么ls在return2的printf后执行

示例:./program /bin/ls

返回

0 
file1
file2
file3

这与换行符(缓冲区相关)无关,因为即使我从 printf 中删除了 \n,行为也是一样的。

我希望 execv 在子​​进程有时间到达 ls 之前立即打印 printf

解决方法

你的父进程不会等待子进程退出,它会在调用function后立即从main返回到fork,然后main也会立即完成它所做的。

甚至可能在子进程开始运行之前父进程就完成了。

使用wait(或相关函数)等待子进程退出,并能够获取其退出码。

,

以下建议代码:

  1. 干净地编译
  2. 检查错误并报告
  3. 执行所需的功能
  4. 父进程等待子进程完成

现在,建议的代码:

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


int function(char **argv) 
{
    pid_t pid = fork();
    if (pid == 0) 
    {  // then child process
        execv(*argv,argv); 
        perror( "execv failed" );
        exit( EXIT_FAILURE );
    }
    
    if( pid < 0 )
    {
        perror( "fork failed" );
        exit( EXIT_FAILURE );
    }
    
    
    //if( pid > 0 )
    // then parent process
    int status;
    waitpid( pid,&status,0 );
        

    return status;
}

int main(int argc,char **argv) 
{
    int return2;
    
    if( argc < 2 )
    {
        fprintf( stderr,"USAGE: %s cmdToRun\n",argv[0] );
        exit( EXIT_FAILURE );
    }
    
    return2 = function(argv+1);
    printf("%d\n",return2);
}