【问题标题】:Getting exit status of terminated process获取终止进程的退出状态
【发布时间】:2021-09-16 04:28:06
【问题描述】:

我正在尝试获取每个进程的退出状态以及它是否返回 1 或 0,并获取每个进程的总和(1 的数量和 0 的数量)。似乎最后一个返回 1 的进程是 while 循环中唯一正在等待的进程。

该程序将文件名作为命令行参数并确定它们是否存在。对于每个文件名(存在与否),一个新进程通过与父级的风扇关系派生,如果文件不存在,则返回错误状态。如果确实存在,则返回成功状态。然而,只有最后一个 PID 显示在 while 循环中。

int main(int argc, char *argv[]) {

    pid_t pid;
    int i, stat, suc = 0, fail = 0;

    if (argc < 2){
        printf("Usage: ./wordcount.exe [File_1] [File_2] [...] [File_n]\n");
        exit(1);
    }

    for (i = 1; i < argc; i++){

        if ((pid = fork()) == 0){

            if (access(argv[i], F_OK) != 0){
                fprintf(stderr, "Child process %ld for %s does not exist\n", (long)getpid(), argv[i]);
                return 1;           
            }
            fprintf(stderr, "Child process %ld for %s: Number of words is: %d\n", (long)getpid(), argv[i], 0);
            exit(0);
        }
    }

    while(1){

        if (waitpid(pid, &stat, 0) == -1 && errno != EINTR) {
            printf("pid var = %d\tstat=%d\n", pid, stat);
            fail++;
            break;
        } else {
            printf("pid var = %d\tstat=%d\n", pid, stat);
            suc++;
        }
    }

    printf("Parent process created %d processes to count %d words in %d files\n", (suc + fail), 0, (suc + fail));
    printf("%d file(s) have been counted successfully!\n", suc);
    printf("%d file(s) did not exist.\n", fail);

    return 0;
}
Current output with 2 existing files and 2 non-existing:

$ ./wordcount.exe input_file_1.txt input_file_2.txt inputfail1 inputfail2
Child process 3565 for input_file_1.txt: Number of words is: 0
Child process 3566 for input_file_2.txt: Number of words is: 0
Child process 3567 for inputfail1 does not exist
Child process 3568 for inputfail2 does not exist
pid var = 3568  stat=256
pid var = 3568  stat=256
Parent process created 2 processes to count 0 words in 2 files
1 file(s) have been counted successfully!
1 file(s) did not exist.

【问题讨论】:

  • 当然,在for 循环的每次迭代中,您都会覆盖变量pid,因此当它完成时,您只会看到最后一个值。如果你想跟踪所有的 pid,一个 int 变量是不够的;你需要一个数组。或使用waitpid(-1, &amp;stat, 0) 等待任何正在奔跑的孩子。
  • 您的if(waitpid(...) == -1) 也不会测试孩子是否返回 0 或 1,它会测试孩子是否存在。所以你的一个“成功”是因为最后一个 pid 的孩子确实退出了(无论是退出代码 0 还是 1,你都没有检查),而你的一个“失败”是因为你试图等待同一个 pid再次,它不再存在,因为你已经在等待它。退出代码在 stat 变量中,您不会在计算 sucfail 时使用其值。
  • 要么将所有 PID 保存在一个数组中,以便您可以等待它们中的每一个。或者使用wait() 而不是waitpid() 这样你就不需要指定PID。

标签: c fork wait waitpid


【解决方案1】:

我综合了你们两个的帮助。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "restartwait.h"

char* ReadLine();

int main(int argc, char *argv[]) {

    pid_t pid[argc - 1];
    int i, stat, suc = 0, fail = 0;

    if (argc < 2){
        printf("Usage: ./wordcount.exe [File_1] [File_2] [...] [File_n]\n");
        exit(1);
    }

    for (i = 1; i < argc; i++){
        pid[i-1] = fork();
        if (pid[i-1] == 0){

            if (access(argv[i], F_OK) != 0){
                fprintf(stderr, "Child process %ld for %s does not exist\n", (long)getpid(), argv[i]);
                return 1;           
            }
            fprintf(stderr, "Child process %ld for %s: Number of words is: %d\n", (long)getpid(), argv[i], 0);
            return 0;
        } else if (pid[i-1] == -1){
            fprintf(stderr, "fork() returned an error. Exiting...\n");
            exit(1);
        } else {
            //parent
            //printf("I am the parent. PID: %d\n", getpid());
        }
    }

    int j=0;
    while (1){
        int x = wait(&stat);
        if (x == -1 && errno != EINTR){
            break;
        }
        //catch errors
        else if (x == -1){
            printf("-1\n");
            break;
        }

        if (stat == 0){
            suc++;
        } else if (stat > 0){
            fail++;
        }
        j++;
    }
    
    printf("Parent process created %d processes to count %d words in %d files\n", (suc + fail), 0, (suc + fail));
    printf("%d file(s) have been counted successfully!\n", suc);
    printf("%d file(s) did not exist.\n", fail);

    return 0;
}

【讨论】:

  • 你能详细解释一下你的代码吗?
  • @JeremyCaney 所以在解决方案中,我正在等待所有带有wait 的孩子,而不是带有waitpid 的特定孩子。该循环永远运行,直到所有孩子都被等待。同时,父母正在检查存储在stat 中的返回状态并相应地增加变量。如果由于某种原因stat 返回了-1,则发生错误并中断。希望能解决这个问题。
猜你喜欢
  • 2012-01-02
  • 2020-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-24
  • 2015-02-03
相关资源
最近更新 更多