【问题标题】:How many processes are created? [closed]创建了多少进程? [关闭]
【发布时间】:2021-07-01 08:27:33
【问题描述】:

我认为这些创建了 5 个流程,但我需要您的验证。 我对这类问题感到困惑。

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

int main()
{
    if (fork()){
        printf("A\n");
        exec("execjune");
    }
    else{
        printf("B\n");
        fork();
        fork();
        exec("execjune");
    }
    printf("D\n");

return 0;
}

【问题讨论】:

  • 为什么您认为这会创建 5 个进程?你对这个推理有什么疑问?
  • 这取决于execjune 的作用。
  • 运行时会发生什么? execjune 程序是什么?没有称为exec() 的标准C 或POSIX 函数(标准名称都有1-3 个后缀字母,例如execve()); exec() 是做什么的?
  • 在研究这样的代码行为时,我发现添加 printf() 调用来打印 PID 以及显着信息很有帮助。并调用fflush() 以确保按预期生成输出。创建一个函数来封装工作。在没有运行代码的情况下,鉴于exec()execve() 的变体并且execjune 打印“C”,我希望在输出中看到A、B 和五个C,而没有D。
  • 如果exec() 函数是execve() 的变体(而不是system() 的变体),那么ifelse 块都会替换@987654337 显示的代码@,并且没有打印 D 的代码路径。

标签: c process operating-system


【解决方案1】:

将 cmets 转换为答案。

当你运行它时会发生什么? execjune 程序是什么?没有称为exec() 的标准C 或POSIX 函数(标准名称都有1-3 个后缀字母,例如execve()); exec() 是做什么的?

如果执行以下程序,并且如果execjune 执行printf("C\n")。我从我的教授那里得到了这个问题,所以我需要问一下这些fork() 语句创建了多少进程。

在研究此类代码的行为时,我发现添加打印 PID 和显着信息的 printf() 调用很有帮助。并调用fflush() 以确保按预期生成输出。创建一个函数来封装工作。在没有运行代码的情况下,鉴于exec()execve() 的变体并且execjune 打印“C”,我希望在输出中看到A、B 和五个C,而没有D。

为什么 D 为 0?我认为 D 是通过main() 方法打印的还是...?

如果exec() 函数是execve() 的变体(而不是system() 的变体),则ifelse 块都替换了execjune 显示的代码,并且有没有打印 D 的代码路径。

这是一些代码。即使在 Linux 上(经过 RHEL 7.4 测试),在 GCC 10.2.0 的默认编译器选项下也没有函数 exec()。所以,我创建了一个函数exec(),还有一个函数dbg_print(),并将它们与代码一起使用(源文件fork97.c编译为可执行fork97):

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

static void dbg_print(const char *fmt, ...)
{
    printf("%d: ", (int)getpid());
    va_list args;
    va_start(args, fmt);
    vprintf(fmt, args);
    va_end(args);
    fflush(stdout);
}

static inline void exec(const char *cmd)
{
    execl(cmd, (char *)0);
}

int main(void)
{
    dbg_print("Initial process\n");
    if (fork()){
    dbg_print("Parent process\n");
        printf("A\n");
        exec("execjune");
    }
    else{
    dbg_print("Child process\n");
        printf("B\n");
        fork();
    dbg_print("Between consecutive fork() calls\n");
        fork();
    dbg_print("After consecutive fork() calls\n");
        exec("execjune");
    }
    printf("D\n");

    return 0;
}

我还使用了从源代码 execjune.c 创建的程序 execjune(它打印一个 PID 以及字母 C):

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

int main(void)
{
    printf("%d: C\n", (int)getpid());
    return 0;
}

当我运行主程序时,我得到如下输出:

$ fork97
28876: Initial process
28876: Parent process
A
28877: Child process
B
28877: Between consecutive fork() calls
28877: After consecutive fork() calls
28879: After consecutive fork() calls
28878: Between consecutive fork() calls
28878: After consecutive fork() calls
28880: After consecutive fork() calls
28876: C
28879: C
$ 28880: C
28878: C
28877: C

$

注意$28880之前的提示符C是因为没有有意义的方法来控制所有子进程在父进程之前退出(部分原因是子进程都执行execjune) .空白行和最后的$ 提示来自我在最后一个 C 行之后按回车。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 2013-11-01
    • 1970-01-01
    相关资源
    最近更新 更多