当前位置: 首页 > news >正文

地方门户类网站建筑资格证书查询官网

地方门户类网站,建筑资格证书查询官网,中国软件邮箱登录入口,广州有哪些知名企业一、fork入门知识 一个进程#xff0c;包括代码、数据和分配给进程的资源。fork#xff08;#xff09;函数通过系统调用创建一个与原来进程几乎完全相同的进程#xff0c;也就是两个进程可以做完全相同的事#xff0c;但如果初始参数或者传入的变量不同#xff0c;两个进…一、fork入门知识 一个进程包括代码、数据和分配给进程的资源。fork函数通过系统调用创建一个与原来进程几乎完全相同的进程也就是两个进程可以做完全相同的事但如果初始参数或者传入的变量不同两个进程也可以做不同的事。     一个进程调用fork函数后系统先给新的进程分配资源例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中只有少数值与原来的进程的值不同。相当于克隆了一个自己。 我们来看一个例子 [cpp] view plaincopy /*  *  fork_test.c  *  version 1  *  Created on: 2010-5-29  *      Author: wangth  */  #include unistd.h  #include stdio.h   int main ()   {       pid_t fpid; //fpid表示fork函数返回的值      int count0;      fpidfork();       if (fpid  0)           printf(error in fork!);       else if (fpid  0) {          printf(i am the child process, my process id is %d/n,getpid());           printf(我是爹的儿子/n);//对某些人来说中文看着更直白。          count;      }      else {          printf(i am the parent process, my process id is %d/n,getpid());           printf(我是孩子他爹/n);          count;      }      printf(统计结果是: %d/n,count);      return 0;  }   运行结果是     i am the child process, my process id is 5574     我是爹的儿子     统计结果是: 1     i am the parent process, my process id is 5573     我是孩子他爹     统计结果是: 1     在语句fpidfork()之前只有一个进程在执行这段代码但在这条语句之后就变成两个进程在执行了这两个进程的几乎完全相同将要执行的下一条语句都是if(fpid0)……     为什么两个进程的fpid不同呢这与fork函数的特性有关。fork调用的一个奇妙之处就是它仅仅被调用一次却能够返回两次它可能有三种不同的返回值     1在父进程中fork返回新创建子进程的进程ID     2在子进程中fork返回0     3如果出现错误fork返回一个负值 在fork函数执行完毕后如果创建新进程成功则出现两个进程一个是子进程一个是父进程。在子进程中fork函数返回0在父进程中fork返回新创建子进程的进程ID。我们可以通过fork返回的值来判断当前进程是子进程还是父进程。 引用一位网友的话来解释fpid的值为什么在父子进程中不同。“其实就相当于链表进程形成了链表父进程的fpid(p 意味point)指向子进程的进程id, 因为子进程没有子进程所以其fpid为0.     fork出错可能有两种原因     1当前的进程数已经达到了系统规定的上限这时errno的值被设置为EAGAIN。     2系统内存不足这时errno的值被设置为ENOMEM。     创建新进程成功后系统中出现两个基本完全相同的进程这两个进程执行没有固定的先后顺序哪个进程先执行要看系统的进程调度策略。     每个进程都有一个独特互不相同的进程标识符process ID可以通过getpid函数获得还有一个记录父进程pid的变量可以通过getppid函数获得变量的值。     fork执行完毕后出现两个进程 有人说两个进程的内容完全一样啊怎么打印的结果不一样啊那是因为判断条件的原因上面列举的只是进程的代码和指令还有变量啊。     执行完fork后进程1的变量为count0fpid0父进程。进程2的变量为count0fpid0子进程这两个进程的变量都是独立的存在不同的地址中不是共用的这点要注意。可以说我们就是通过fpid来识别和操作父子进程的。     还有人可能疑惑为什么不是从#include处开始复制代码的这是因为fork是把进程当前的情况拷贝一份执行fork时进程已经执行完了int count0;fork只拷贝下一个要执行的代码到新的进程。 二、fork进阶知识 先看一份代码 [cpp] view plaincopy /*  *  fork_test.c  *  version 2  *  Created on: 2010-5-29  *      Author: wangth  */  #include unistd.h  #include stdio.h  int main(void)  {     int i0;     printf(i son/pa ppid pid  fpid/n);     //ppid指当前进程的父进程pid     //pid指当前进程的pid,     //fpid指fork返回给当前进程的值     for(i0;i2;i){         pid_t fpidfork();         if(fpid0)             printf(%d child  %4d %4d %4d/n,i,getppid(),getpid(),fpid);         else             printf(%d parent %4d %4d %4d/n,i,getppid(),getpid(),fpid);     }     return 0;  }   运行结果是     i son/pa ppid pid  fpid     0 parent 2043 3224 3225     0 child  3224 3225    0     1 parent 2043 3224 3226     1 parent 3224 3225 3227     1 child     1 3227    0     1 child     1 3226    0     这份代码比较有意思我们来认真分析一下     第一步在父进程中指令执行到for循环中i0接着执行forkfork执行完后系统中出现两个进程分别是p3224和p3225后面我都用pxxxx表示进程id为xxxx的进程。可以看到父进程p3224的父进程是p2043子进程p3225的父进程正好是p3224。我们用一个链表来表示这个关系     p2043-p3224-p3225     第一次fork后p3224父进程的变量为i0fpid3225fork函数在父进程中返向子进程id代码内容为 [c-sharp] view plaincopy for(i0;i2;i){      pid_t fpidfork();//执行完毕i0fpid3225      if(fpid0)         printf(%d child  %4d %4d %4d/n,i,getppid(),getpid(),fpid);      else         printf(%d parent %4d %4d %4d/n,i,getppid(),getpid(),fpid);  }  return 0;   p3225子进程的变量为i0fpid0fork函数在子进程中返回0代码内容为 [c-sharp] view plaincopy for(i0;i2;i){      pid_t fpidfork();//执行完毕i0fpid0      if(fpid0)         printf(%d child  %4d %4d %4d/n,i,getppid(),getpid(),fpid);      else         printf(%d parent %4d %4d %4d/n,i,getppid(),getpid(),fpid);  }  return 0;   所以打印出结果     0 parent 2043 3224 3225     0 child  3224 3225    0     第二步假设父进程p3224先执行当进入下一个循环时i1接着执行fork系统中又新增一个进程p3226对于此时的父进程p2043-p3224当前进程-p3226被创建的子进程。     对于子进程p3225执行完第一次循环后i1接着执行fork系统中新增一个进程p3227对于此进程p3224-p3225当前进程-p3227被创建的子进程。从输出可以看到p3225原来是p3224的子进程现在变成p3227的父进程。父子是相对的这个大家应该容易理解。只要当前进程执行了fork该进程就变成了父进程了就打印出了parent。     所以打印出结果是     1 parent 2043 3224 3226     1 parent 3224 3225 3227      第三步第二步创建了两个进程p3226p3227这两个进程执行完printf函数后就结束了因为这两个进程无法进入第三次循环无法fork该执行return 0;了其他进程也是如此。     以下是p3226p3227打印出的结果     1 child     1 3227    0     1 child     1 3226    0     细心的读者可能注意到p3226p3227的父进程难道不该是p3224和p3225吗怎么会是1呢这里得讲到进程的创建和死亡的过程在p3224和p3225执行完第二个循环后main函数就该退出了也即进程该死亡了因为它已经做完所有事情了。p3224和p3225死亡后p3226p3227就没有父进程了这在操作系统是不被允许的所以p3226p3227的父进程就被置为p1了p1是永远不会死亡的至于为什么这里先不介绍留到“三、fork高阶知识”讲。     总结一下这个程序执行的流程如下 这个程序最终产生了3个子进程执行过6次printf函数。     我们再来看一份代码 [cpp] view plaincopy /*  *  fork_test.c  *  version 3  *  Created on: 2010-5-29  *      Author: wangth  */  #include unistd.h  #include stdio.h  int main(void)  {     int i0;     for(i0;i3;i){         pid_t fpidfork();         if(fpid0)             printf(son/n);         else             printf(father/n);     }     return 0;    }   它的执行结果是     father     son     father     father     father     father     son     son     father     son     son     son     father     son     这里就不做详细解释了只做一个大概的分析。     for        i0         1           2               father     father     father                                         son                             son       father                                         son                son       father     father                                         son                             son       father                                         son     其中每一行分别代表一个进程的运行打印结果。     总结一下规律对于这种N次循环的情况执行printf函数的次数为2*124……2N-1次创建的子进程数为124……2N-1个。(感谢gao_jiawei网友指出的错误原本我的结论是“执行printf函数的次数为2*124……2N次创建的子进程数为124……2N ”这是错的)     网上有人说N次循环产生2*124……2N个进程这个说法是不对的希望大家需要注意。 数学推理见http://202.117.3.13/wordpress/?p81该博文的最后。     同时大家如果想测一下一个程序中到底创建了几个子进程最好的方法就是调用printf函数打印该进程的pid也即调用printf(%d/n,getpid());或者通过printf(/n);来判断产生了几个进程。有人想通过调用printf();来统计创建了几个进程这是不妥当的。具体原因我来分析。     老规矩大家看一下下面的代码 [cpp] view plaincopy /*  *  fork_test.c  *  version 4  *  Created on: 2010-5-29  *      Author: wangth  */  #include unistd.h  #include stdio.h  int main() {      pid_t fpid;//fpid表示fork函数返回的值      //printf(fork!);      printf(fork!/n);      fpid  fork();      if (fpid  0)          printf(error in fork!);      else if (fpid  0)          printf(I am the child process, my process id is %d/n, getpid());      else          printf(I am the parent process, my process id is %d/n, getpid());      return 0;  }   执行结果如下     fork!     I am the parent process, my process id is 3361     I am the child process, my process id is 3362     如果把语句printf(fork!/n);注释掉执行printf(fork!);     则新的程序的执行结果是     fork!I am the parent process, my process id is 3298     fork!I am the child process, my process id is 3299     程序的唯一的区别就在于一个/n回车符号为什么结果会相差这么大呢     这就跟printf的缓冲机制有关了printf某些内容时操作系统仅仅是把该内容放到了stdout的缓冲队列里了,并没有实际的写到屏幕上。但是,只要看到有/n 则会立即刷新stdout,因此就马上能够打印了。     运行了printf(fork!)后,“fork!”仅仅被放到了缓冲里,程序运行到fork时缓冲里面的“fork!”  被子进程复制过去了。因此在子进程度stdout缓冲里面就也有了fork! 。所以,你最终看到的会是fork!  被printf了2次     而运行printf(fork! /n)后,“fork!”被立即打印到了屏幕上,之后fork到的子进程里的stdout缓冲里不会有fork! 内容。因此你看到的结果会是fork! 被printf了1次     所以说printf();不能正确地反应进程的数量。     大家看了这么多可能有点疲倦吧不过我还得贴最后一份代码来进一步分析fork函数。 [cpp] view plaincopy #include stdio.h  #include unistd.h  int main(int argc, char* argv[])  {     fork();     fork()  fork() || fork();     fork();     return 0;  }   问题是不算main这个进程自身程序到底创建了多少个进程。     为了解答这个问题我们先做一下弊先用程序验证一下到此有多少个进程。 [c-sharp] view plaincopy #include stdio.h  int main(int argc, char* argv[])  {     fork();     fork()  fork() || fork();     fork();     printf(/n);  }   答案是总共20个进程除去main进程还有19个进程。     我们再来仔细分析一下为什么是还有19个进程。     第一个fork和最后一个fork肯定是会执行的。     主要在中间3个fork上可以画一个图进行描述。     这里就需要注意和||运算符。     AB如果A0就没有必要继续执行B了A非0就需要继续执行B。     A||B如果A非0就没有必要继续执行||B了A0就需要继续执行||B。     fork()对于父进程和子进程的返回值是不同的按照上面的AB和A||B的分支进行画图可以得出5个分支。 加上前面的fork和最后的fork总共4*520个进程除去main主进程就是19个进程了。 三、fork高阶知识 这一块我主要就fork函数讲一下操作系统进程的创建、死亡和调度等。因为时间和精力限制我先写到这里下次找个时间我争取把剩下的内容补齐。 参考资料 http://blog.csdn.net/dog_in_yellow/archive/2008/01/13/2041079.aspx http://blog.chinaunix.net/u1/53053/showart_425189.html http://blog.csdn.net/saturnbj/archive/2009/06/19/4282639.aspx http://www.cppblog.com/zhangxu/archive/2007/12/02/37640.html http://www.qqread.com/linux/2010/03/y491043.html http://www.yuanma.org/data/2009/1103/article_3998.htm
http://www.pierceye.com/news/46193/

相关文章:

  • 保定网站建设方案咨询手机网站导航栏如何做
  • 哪里的网站可以做围棋死活题专做宝宝辅食的网站
  • 做网站用商标吗最新军事新闻头条
  • 长沙专业建设网站企业岳阳新网网站建设有限公司
  • 男做暧免费视频网站网站推广方式推荐
  • 制作商城版网站开发大网站制作公司
  • 网站建设课网站免费建立
  • 做一个网站价格网站广告位价格一般多少
  • Hdi做指数网站wordpress添加html页面
  • 广州 网站的设计公司怎么学做电商然后自己创业
  • 哪个网站可以做微信引导图推广资源整合平台
  • 昆明网站开发公司电话网站建设的一些销售技巧
  • 广州seo网站推广公司地方购物网站盈利模式
  • 高端企业建站公司免费下载应用市场
  • 网站开发岗位思维导图刷关键词要刷大词吗
  • 网站规划与开发牛魔王网站建设
  • 织梦做的网站首页打不开wordpress新建html
  • 苏州建设网站服务中国制造网网站建设的优势
  • 福田汽车官网报价大全光泽网站建设wzjseo
  • 网站模板 介绍注册电子邮箱免费注册
  • 上海做网站建设公司wordpress页面怎么编辑器
  • 专业郑州做网站招投标相关政策
  • 网页设计师必须知道的网站专做动漫解说的网站
  • 深圳网站建设深正互联ps做简洁大气网站
  • 网站空间到期提示wordpress主题2019
  • 网站服务器有哪些家装设计平台
  • 时尚网站设计wordpress询盘功能
  • 自适应网站 与响应式外包公司驻场能不能去
  • 个人网站备案模板电子商务网站建设书
  • wordpress 仿花瓣优化建站