【问题标题】:Why is an execv slower than a printf after a fork in a c program?为什么在 c 程序中分叉后 execv 比 printf 慢?
【发布时间】:2021-06-12 11:32:48
【问题描述】:

假设我有以下名为 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 在子​​进程有时间到达printf 之前立即打印ls

【问题讨论】:

  • 对于未来的问题,请花一些时间接受 SO tour、阅读 How to Ask 以及 this question checklist。您需要解释问题正文中的预期行为以及实际行为。我的回答其实只是对问题的猜测
  • 变量resultvalue的作用是什么?
  • result 变量没用,value 变量用于测试哪个最快,execvprintf。它只是表示要打印的值。
  • 但是你并没有真正测量 execv 调用本身的时间,你正在测量你的小 ans 快速程序与完整的 ls 程序,这将是相当慢的(通过数量级)。
  • OT: regaarding: return2 = function(argv+1); 在没有首先检查argc 以确保用户实际输入命令行参数之前,不要访问argv[0] 以外的地方。否则对argv[1]的访问将访问一个NULL值

标签: c printf ls execv


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    以下建议的代码:

    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);
    }
    

    【讨论】:

      猜你喜欢
      • 2017-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-15
      • 2012-03-11
      • 2015-10-04
      • 2012-02-19
      • 1970-01-01
      相关资源
      最近更新 更多