看这一段代码,我想了一会儿,然后实验了一下午。
#include <unistd.h> #include <stdio.h> int main() { pid_t pid; pid=fork(); if(pid==0){ while(1){ sleep(1); printf("haha\n"); } } if(pid>0) { while(1){ sleep(1); printf("hehe\n"); } } }
代码显而易懂,我开始想不明白,如果按照顺序结构结构,那么肯定会陷入死循环,要么一直打印出haha,要么一直打印出hehe。
事后,将代码改了该,然后发现了一些规律,然后总结出fork() 函数的功能。
注: PID:进程号 PPID:父进程号;TIME : 占用CPU的时间
我分了以下几种情况。
第一种: 注释掉第一个while语句中的sleep() 函数,得到如下结果
PID | PPID | TIME |
6060 | 3520 | 00;00;00 |
6061 | 6060 | 00;00;07 |
程序运行结果为 haha haha 。。。
第二种: 注释掉第二个while语句中的 sleep() 函数,得到如下结果:
PID | PPID | TIME |
6235 | 3520 | 00:00:01 |
6236 | 6235 | 00:00:00 |
程序运行结果为 hehe hehe 。。。
第三种 :保留两个while语句的sleep()函数,得到如下结果
PID | PPID | TIME |
6238 | 3520 | 00:00:00 |
6239 | 6328 | 00:00:00 |
程序运行结果为 : hehe haha hehe haha 。。。
其实程序很简单,如果按照正常的程序执行顺序,为顺序执行,结果想了好久都想不通,终于经过一番折腾后,发现了一些信息。
很显然,如果只保留两个sleep中的一个,则会陷入一个死循环里;如果两者都保留,会交替出现所打印出的字符;显然,sleep()函数具有使进程休眠的作用,并让出CPU;按照这样理解的话,交替出现字符的现象也能理解。其次,子进程是从父进程分出来的,可以从进程号中看出,而且,子进程的初始化进程号为0。从最后的结果看出,进程可以在两者之间切换,且占用CPU的时间几乎为0.(其实,也可以从占用CPU的时间中发现到底是哪个进程在运行)
总结一下,UNIX中的 fork()函数, procid=fork() ,这条语句的执行简单的把称作为 parent 的当前进程进行复制。父进程和新创建的被称作“孩子”的进程的唯一区别是变量 procid;
父进程中它的值是子进程的进程号,而在子进程·中这个值是0.这样就允许两个进城都可以以确定的标识并各自运行。一般来说, fork() 语句后是如下形式:
if(procid==0) do child_processing; else do parent processing;
两个进程之中的某一个,比如说子进程,可能通过在 do_child_processing 语句中的某处执行系统调用exec () 覆盖自身。这个函数指定一个新的程序作为起参数之一,
然后新的进程作为子进程继续执行。
原文地址:https://www.cnblogs.com/guoyu1024/p/9704211.html