当前位置:编程学习 > 网站相关 >>

关于进程创建

  最近看《Unix环境高级编程》,其中有讲到创建子线程用fork的函数调用,这个函数特别之处是调用一次,返回两次,分别为0和pid,这里假定每次创建都是成功的。
为啥返回两次呢,而且值不一样呢?

       返回两次是系统调用的实现,需要查看fork是如何实现的,这里面就比较复杂了,鄙人现在不懂。

       返回值不同,创建进程返回新生进程的id值,新生进程返回0,每一个进程的父进程是确定的,可以通过getppid来获取,但子进程的个数可以不止一个,所以父进程中返回新生进程的id值。

      然后需要注意的是fork和vfork的区别,fork一个新生进程,(进程--资源分配的最小单位哦,亲),新生进程和父进程是共享代码段的,但数据段是父进程的拷贝,而vfork后,新生进程和父进程共享代码段也共享数据段,不是拷贝。

     当然fork之后,是新生进程先执行,还是父进程先执行,取决于进程调度,调度顺序不一定。

     好了,废话扯了一堆,来看看下面的一道面试题目:

微软的一个选择题目,问输出的"-"有多少个?2个 4个 6 个 还是8个?

  1 #include<stdio.h>
  2 #include<sys/types.h>
  3 #include<unistd.h>
  4 int main(int argc ,char **argv)
  5 {
  6         int i;
  7         for(i=0;i<2;i++)
  8         {
  9                 fork();
 10                 printf("-");
 11         }
 12         return 0;
 13 }
按照书上面讲的来分析一下,假定初始化的进程id为IDNUM,

<1>

 当他执行到9的时候,成功创建了一个新生进程,假定id为IDNUM+1

 这时IDNUM和IDNUM+1分别打印了一次,个数为2,执行拷贝数据,所以新生进程的i值现在为0

然后执行for循环的第3部分,这时IDNUM 和IDNUM+1的i值都变为了1

 

<2>

执行for循环的第2部分,再次执行到9行,进程为IDNUM的进程产生新的进程,假定为IDNUM+2

进程为IDNUM+1的进程产生新的进程,假定为IDNUM+3

 这时新生进程IDNUM+2和新生进程IDNUM+3执行数据拷贝他们的i值现在为1

这时每个进程都打印了1次,所以个数为2+4=6个

这之后执行for循环体第3部分,现在所以的进程的i值都变为了2

<3>

执行for循环的第2部分,条件不成立,for循环结束,之后执行return 0.由于没有写信号处理函数,系统负责SIGEND SIGCHID的处理,这时候执行抛弃?还是啥,不记得了,但系统会负责资源的回收,是否会产生僵死进程呢,等下不防试验一下。看看有没有被挂到1号进程上面的新进程。理论完了,看看分析对不对,下面的部分是实验所得。

 

实验部分:

      说明:使用的系统未ubuntu 10.04LTS版本64位,2.6.32内核

实验一

     把上述用vi编辑好后,采用gcc -o fork  fork.c 编译,运行之后得到的结果是:

                                                                                                                                                                                                                                                                                                                                                 

 

是不是很奇怪呢,打印出了8个-,不是之前我yy的6个。先别急,毕竟这本书粗略的看了一下,对linux也还没入门好吧

等下进一步分析。

实验二

接下来的一个题目非常有意思为啥这么说,因为不仔细看,还以为题目出重复了

  1 #include<stdio.h>
  2 #include<sys/types.h>
  3 #include<unistd.h>
  4 int main(int argc ,char **argv)
  5 {
  6         int i;
  7         for(i=0;i<2;i++)
  8         {
  9                 fork();
 10                 printf("-\n");
 11         }
 12         return 0;
 13 }
和上面的题目唯一的区别就是在第10行的输出部分,加入了回车换行,仍然问输出的“-”有多少个?2个 4个 6个 还是8个?

也不墨迹了,直接跑起来,下面是实验结果:

 

这次貌似对了6个“-”,和我之前yy的结果是一样的,但别得意,为啥这么大的区别,到底是为什么呢?缓冲区?引用计数?信号处理?

蛋在这个时候已经不复存在。

还望高人指点一二。

那就在深究一下好了,还是实验,通过加入getpid和getppid来看看输出。

实验三

在实验二的基础上,稍微改动一下好了

 

ok,运行结果呢:

 

跟我上面yy的基本上符合,5303号进程为shell进程id吧,6493为shell为执行体第一加载的进程id,

输出的内容会不一定,因为每次加载时分配的进程id是按照未分配的进程id往上加的,且进程之间执行顺序的先后,和系统进程调用环境有关,

贴个证据:

 

除了shell的pid是相同的,最后有一个进程的父id挂为了1,有僵死进程出现,何谓僵死进程,就是创建它的父进程已经消亡,子进程还没运行完毕

这时系统会把这些进程挂到1号进程上去,成为1号进程的子进程

实验结果就是:和我yy的过程是一致的,下面查看下系统的进程,可以通过/proc目录,也可以用ps命令查看一下,不过发现找不到进程id为6584这样的进程,

补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,