【问题标题】:fork starts executing form where?fork 从哪里开始执行?
【发布时间】:2011-03-05 19:52:42
【问题描述】:

关于我之前关于分段错误的问题,我得到了非常有用的答案。感谢那些回答的人。

#include<stdio.h>
main()
{
 printf("hello");
int pid = fork();
wait(NULL);
}

输出:你好。

在这种情况下,子进程从头开始执行。 如果我没有错,那么如果我将 sem_open 放在 fork() 之前,程序将如何工作 (参考答案:prev questions)

我需要一个关于分段错误的清晰解释,这种错误偶尔会发生,但并不总是发生。为什么不总是...如果编码中有任何错误,那么它应该总是正确...?

【问题讨论】:

标签: c linux segmentation-fault fork semaphore


【解决方案1】:

fork 创建您的进程的克隆。从概念上讲,父母的所有状态也最终在孩子身上。这包括:

  • CPU 寄存器(包括指令指针,它定义了程序在代码中的位置)
  • 内存(作为一种优化,您的内核很可能会将所有页面标记为写时复制,但从语义上讲,它应该与复制所有内存相同。)
  • 文件描述符

因此...您的程序不会从任何地方“开始运行”...您调用fork 时的所有状态都将传播给子进程。孩子将从fork 返回,就像父母一样。

至于分叉后你可以做什么......我不确定 POSIX 说了什么,但我不会依赖信号量在fork 之后做正确的事情。您可能需要一个进程间信号量(请参阅man sem_open,或sem_initpshared 参数)。根据我的经验,跨进程信号量在免费的 Unix 类型操作系统上并没有得到很好的支持...(例如:如果您尝试创建一个 BSD,某些 BSD 总是以ENOSYS 失败。)

@GregS 在分叉后提到了重复的“hello”字符串。他说stdio(即FILE*)将在用户空间内存中缓冲是正确的,而fork导致字符串在两个进程中缓冲。您可能想调用fflush(stdout); fflush(stderr); 并在fork 之前刷新任何其他重要的FILE* 句柄。

【讨论】:

  • @GregS - 是的,你完全正确。我将此纳入答案。谢谢!
【解决方案2】:

不,它从fork()开始,它在child中返回0或者在parent中返回child的进程ID。

您会看到两次“hello”,因为标准输出已缓冲,实际上并未在分叉点写入。然后,父母和孩子都实际写入缓冲的输出。如果你在printf() 之后fflush(stdout);,你应该只看到一次。

【讨论】:

    猜你喜欢
    • 2021-12-08
    • 1970-01-01
    • 2022-01-05
    • 2018-12-13
    • 1970-01-01
    • 2018-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多