当前位置:网站首页 > 技术博客 > 正文

linux的for语句



目录

linux中fork()函数详解

从一道面试题谈linux下fork的运行机制

原文:linux中fork()函数详解(原创!!实例讲解)_jason314的博客-CSDN博客_fork()函数

一、fork入门知识

     一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,

也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。

复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。

我们来看一个例子:

    在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。我们可以通过fork返回的值来判断当前进程是子进程还是父进程。

    fpid的值为什么在父子进程中不同。“其实就相当于链表,进程形成了链表,父进程的fpid(p 意味point)指向子进程的进程id, 因为子进程没有子进程,所以其fpid为0.

//------------------------------------------------------------以下还没研读-----------------------------------

二、fork进阶知识

运行结果是:

这份代码比较有意思,我们来认真分析一下:

1、第一步:在父进程中,指令执行到for循环中,i=0,接着执行fork,fork执行完后,系统中出现两个进程,分别是p3224和p3225(后面我都用pxxxx表示进程id为xxxx的进程)。可以看到父进程p3224的父进程是p2043,子进程p3225的父进程正好是p3224。我们用一个链表来表示这个关系:

p3225(子进程)的变量为i=0,fpid=0(fork函数在子进程中返回0),代码内容为:

它的执行结果是:

执行结果如下:

这里就需要注意&&和||运算符。

A&&B,如果A=0,就没有必要继续执行&&B了;A非0,就需要继续执行&&B。

A||B,如果A非0,就没有必要继续执行||B了,A=0,就需要继续执行||B。

fork()对于父进程和子进程的返回值是不同的,按照上面的A&&B和A||B的分支进行画图,可以得出5个分支。

三、fork高阶知识

        这一块我主要就fork函数讲一下操作系统进程的创建、死亡和调度等。因为时间和精力限制,我先写到这里,下次找个时间我争取把剩下的内容补齐。

参考资料:

      http://blog.csdn.net/dog_in_yellow/archive/2008/01/13/.aspx

      http://blog.chinaunix.net/u1/53053/showart_425189.html

      http://blog.csdn.net/saturnbj/archive/2009/06/19/.aspx

      http://www.cppblog.com/zhangxu/archive/2007/12/02/37640.html

      http://www.read.com/linux/2010/03/y491043.html

2020-07-13 02:01:36 发布

(原文::http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E7%9F%A5%E8%AF%86%E5%BA%93/3519.shtml)

今天一位朋友去一个不错的外企面试linux开发职位,面试官出了一个如下的题目:

      给出如下c程序,在linux下使用gcc编译:

 #include "stdio.h" #include "sys/types.h" #include "unistd.h" int main() { pid_t pid1; pid_t pid2; pid1 = fork(); pid2 = fork(); printf("pid1:%d, pid2:%d ", pid1, pid2); } 

      要求如下:

      已知从这个程序执行到这个程序的所有进程结束这个时间段内,没有其它新进程执行。

      1、请说出执行这个程序后,将一共运行几个进程。

      2、如果其中一个进程的输出结果是“pid1:1001, pid2:1002”,写出其他进程的输出结果(不考虑进程执行顺序)。

      明显这道题的目的是考察linux下fork的执行机制。下面我们通过分析这个题目,谈谈linux下fork的运行机制。

  预备知识

      这里先列出一些必要的预备知识,对linux下进程机制比较熟悉的朋友可以略过。

      1、进程可以看做程序的一次执行过程。在linux下,每个进程有唯一的pid标识进程。pid是一个从1到32768的正整数,其中1一般是特殊进程init,其它进程从2开始依次编号。当用完32768后,从2重新开始。

      2、linux中有一个叫进程表的结构用来存储当前正在运行的进程。可以使用“ps aux”命令查看所有正在运行的进程。

      3、进程在linux中呈树状结构,init为根节点,其它进

此文来自: 马开东博客 转载请注明出处 网址:

程均有父进程,某进程的父进程就是启动这个进程的进程,这个进程叫做父进程的子进程。

      4、fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。

  解题的关键

      有了上面的预备知识,我们再来看看解题的关键。我认为,解题的关键就是要认识到fork将程序切成两段。看下图:

      上图表示一个含有fork的程序,而fork语句可以看成将程序切为a、b两个部分。然后整个程序会如下运行:

      step1、设由shell直接执行程序,生成了进程p。p执行完part. a的所有代码。

      step2、当执行到pid = fork();时,p启动一个进程q,q是p的子进程,和p是同一个程序的进程。q继承p的所有变量、环境变量、程序计数器的当前值。

      step3、在p进程中,fork()将q的pid返回给变量pid,并继续执行part. b的代码。

      step4、在进程q中,将0赋给pid,并继续执行part. b的代码。

      这里有三个点非常关键:

      1、p执行了所有程序,而q只执行了part. b,即fork()后面的程序。(这是因为q继承了p的pc-程序计数器)

      2、q继承了fork()语句执行时当前的环境,而不是程序的初始环境。

      3、p中fork()语句启动子进程q,并将q的pid返回,而q中的fork()语句不启动新进程,仅将0返回。

  解题

      下面利用上

此文来自: 马开东博客 转载请注明出处 网址:

文阐述的知识进行解题。这里我把两个问题放在一起进行分析。

      1、从shell中执行此程序,启动了一个进程,我们设这个进程为p0,设其pid为xxx(解题过程不需知道其pid)。

      2、当执行到pid1 = fork();时,p0启动一个子进程p1,由题目知p1的pid为1001。我们暂且不管p1。

      3、p0中的fork返回1001给pid1,继续执行到pid2 = fork();,此时启动另一个新进程,设为p2,由题目知p2的pid为1002。同样暂且不管p2。

      4、p0中的第二个fork返回1002给pid2,继续执行完后续程序,结束。所以,p0的结果为“pid1:1001, pid2:1002”。

      5、再看p2,p2生成时,p0中pid1=1001,所以p2中pid1继承p0的1001,而作为子进程pid2=0。p2从第二个fork后开始执行,结束后输出“pid1:1001, pid2:0”。

      6、接着看p1,p1中第一条fork返回0给pid1,然后接着执行后面的语句。而后面接着的语句是pid2 = fork();执行到这里,p1又产生了一个新进程,设为p3。先不管p3。

      7、p1中第二条fork将p3的pid返回给pid2,由预备知识知p3的pid为1003,所以p1的pid2=1003。p1继续执行后续程序,结束,输出“pid1:0, pid2:1003”。

      8、p3作为p1的子进程,继承p1中pid1=0,并且第二条fork将0返回给pid2,所以p3最后输出“pid1:0, pid2:0”。

      9、至此,整个执行过程完毕。

      所得答案:

      1、一共执行了四个进程。(p0, p1, p2, p3)

      2、另外几个进程的输出分别为:

      pid1:1001, pid2:0

      pid1:0, pid2:1003

      pid1:0, pid2:0

      进一步可以给出一个以p0为根的进程树:

  验证

      下面我们去linux下实际执行这个程序,来验证我们的答案。

      程序如下图:

      用gcc编译、执行后结果如下:

      由于我们不太可能刚巧碰上pid分配到1001的情况,所以具体数值可能和答案有所差别。不过将这里的2710看做基数的话,结果和我们上面的解答是一致的。

  总结

      应该说这不是一道特别难或特别*钻的题目,但是由于fork函数

http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E7%9F%A5%E8%AF%86%E5%BA%93/3519.shtml

  • 上一篇: eof函数用法
  • 下一篇: python unittest mock
  • 版权声明


    相关文章:

  • eof函数用法2025-06-27 20:01:01
  • redis集群与哨兵的选择2025-06-27 20:01:01
  • 安卓开机动画下载2025-06-27 20:01:01
  • mysql怎么连接数据库2025-06-27 20:01:01
  • application/json 请求头的2025-06-27 20:01:01
  • python unittest mock2025-06-27 20:01:01
  • async/await python2025-06-27 20:01:01
  • hashcode和equals方法的关系2025-06-27 20:01:01
  • 什么是积分运算电路2025-06-27 20:01:01
  • 逻辑回归的原理和应用2025-06-27 20:01:01