C 子级和父级的执行流

C 子级和父级的执行流,c,memory-management,binary,gdb,posix,C,Memory Management,Binary,Gdb,Posix,在网上读到我无法真正确定哪个进程在运行之前,即子进程还是父进程后,我计划在我的电脑上禁用ASLR并运行调试器以查看是否可以生成执行模式,下面是我的观察结果,并附上GDB disas(完整)的GitGist和源代码 #include<stdio.h> #include<sys/types.h> #include<unistd.h> int main() { fork(); //fork(); printf("LINUX\n"); //printf("my pid

在网上读到我无法真正确定哪个进程在运行之前,即
子进程还是父进程
后,我计划在我的电脑上禁用ASLR并运行调试器以查看是否可以生成执行模式,下面是我的观察结果,并附上GDB disas(完整)的GitGist和源代码

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
fork();
//fork();
printf("LINUX\n");
//printf("my pid is %d",(int) getpid());
fork();
printf("REDHAT\n");
//printf("my pid is %d",(int) getpid());

//fork();
return 0;
}
这与我在disas中的观察不一致,有人能填补我理解上的空白吗


每个进程都以完美定义的顺序执行。这里的诀窍是,不能保证每个进程将在一个刻度(进程占用执行单元的时间段)内执行,也不能保证从同一进程分叉的两个进程将按照分叉的顺序获得刻度

如果我们假设A(LINUX)和B(REDHAT)的打印是基准,那么您可以获得任意As和Bs序列,前提是:

  • 序列以A开头
  • 总共有两个As和四个Bs
  • 每个A后面有两个B
AABBBB
ababbbb
阿巴伯

是抢占式多任务操作系统上所有可能的输出


另外,如果没有Employed所说的话,这个答案是不完整的。

每个过程都以完美定义的顺序执行。这里的诀窍是,不能保证每个进程将在一个刻度(进程占用执行单元的时间段)内执行,也不能保证从同一进程分叉的两个进程将按照分叉的顺序获得刻度

如果我们假设A(LINUX)和B(REDHAT)的打印是基准,那么您可以获得任意As和Bs序列,前提是:

  • 序列以A开头
  • 总共有两个As和四个Bs
  • 每个A后面有两个B
AABBBB
ababbbb
阿巴伯

是抢占式多任务操作系统上所有可能的输出

另外,如果没有Employee所说的话,这个答案是不完整的

我试了三次disas main,看看顺序是否有变化

顺序在编译时是固定的,因此如果不重新编译程序,它永远不会改变

此外,顺序是由程序源确定的——编译器不允许对输出重新排序

然后,您观察到的是操作系统由于调用
fork
而引入的不确定性--
fork
之后,无法保证哪个进程将首先运行,或者运行多长时间。父级可以运行到完成,然后是子级。或者孩子可以先跑完。或者它们都可以使用时间切片运行,比如说一次一行

此外,今天大多数非古代Linux系统都运行在多处理器机器上,这两个独立的进程可以在fork之后同时运行

另一个复杂的问题是,由于stdio缓冲,您的程序没有得到很好的定义。当您看到6行输出时,您可能很难解释此结果:

./forkagain | wc -l
8
./forkagain > junk.out; cat junk.out
LINUX
REDHAT
LINUX
REDHAT
LINUX
REDHAT
LINUX
REDHAT
您应该添加
fflush(stdout)fork
之前编码>以避免这种复杂情况

另外,你还应该改掉以root用户身份运行的坏习惯——迟早你会犯一个愚蠢的错误(比如在错误的目录中键入
rm-rf*
),并且会为你以root用户身份运行感到非常抱歉

我试了三次disas main,看看顺序是否有变化

顺序在编译时是固定的,因此如果不重新编译程序,它永远不会改变

此外,顺序是由程序源确定的——编译器不允许对输出重新排序

然后,您观察到的是操作系统由于调用
fork
而引入的不确定性--
fork
之后,无法保证哪个进程将首先运行,或者运行多长时间。父级可以运行到完成,然后是子级。或者孩子可以先跑完。或者它们都可以使用时间切片运行,比如说一次一行

此外,今天大多数非古代Linux系统都运行在多处理器机器上,这两个独立的进程可以在fork之后同时运行

另一个复杂的问题是,由于stdio缓冲,您的程序没有得到很好的定义。当您看到6行输出时,您可能很难解释此结果:

./forkagain | wc -l
8
./forkagain > junk.out; cat junk.out
LINUX
REDHAT
LINUX
REDHAT
LINUX
REDHAT
LINUX
REDHAT
您应该添加
fflush(stdout)fork
之前编码>以避免这种复杂情况


另外,你还应该改掉以root用户身份运行的坏习惯——迟早你会犯一个愚蠢的错误(比如在错误的目录中键入
rm-rf*
),并且会非常后悔你是以root用户身份运行的。

多核cpu将有一个选项,在fork之后,两个进程都是并发的“都是可能的输出”--其他输出也是可能的--请参阅我的答案。多核cpu将有一个选项,在fork之后,两个进程都是并发的“都是可能的输出”--其他输出也是可能的--请参阅我的答案。非常感谢您的出色输入!因此,在调试器上实现了多处理,不确定在哪里,但在一些博客上我读到,调试器内部只使用单核来轻松观察代码流……非常感谢您的出色输入!所以在调试器上实现了多处理,不确定在哪里,但在一些博客上我读到,调试器内部只使用单核来轻松观察代码流。。。
./forkagain | wc -l
8
./forkagain > junk.out; cat junk.out
LINUX
REDHAT
LINUX
REDHAT
LINUX
REDHAT
LINUX
REDHAT