• Linux系列


      进程 (Process)是指操作系统中被加载到内存中的、正在运行的应用程序实例。进程是系统资源分配的基本单元,在其生命周期内会使用系统中的各种资源。进程主要由程序、数据以及进程控制快(PCB)3个部分组成。关于其基本知识和其状态相关的知识就不介绍了。下面来看看进程的创建和操作吧。

      当然,Linux系统中创建进程的函数调用很多(如:system()、popen()等等),此处,主要介绍下fork()函数:

    /* Clone the calling process, creating an exact copy.
       Return -1 for errors, 0 to the new process,
       and the process ID of the new process to the old process.  */
    extern __pid_t fork (void) __THROWNL;

      用户可以通过Linux系统提供的fork()来创建多个子线程一实现多个不同任务的并发执行。若创建成功,则从子线程返回0,从父线程返回大于0的正整数(即子线程的惟一标识符id),否则返回-1,表示创建失败。

      操作系统内核为完成fork()调用执行的有以下操作:(1)为新进程分配一进程表项和进程标识符,操作系统会检查系统是否有足够的资源来建立一个新进程(2)检查同时存在且正在运行的进程数目,若超过预先规定的最大进程数目,fork()系统调用将会失败。(3)拷贝进程表项中的数据,将父进程的当前记录和所有已打开的数据拷贝到子进程表项中,并置进程的状态为“创建”状态。(4)子进程继承父进程的所有文件(5)为子进程创建进程上下文(6)执行子进程,虽然父进程和子进程程序完全相同,但每个进程都有自己的程序计数器PC,并根据fork()返回值的不同,执行不同的分支语言。因此,可以确定fork()是通过复制当前进程来创建新进程的。

    #include<stdio.h>
    #include<unistd.h>
    int main()
    {
      int pid;
      pid=fork();
      while(pid==-1);//创建子进程直到成功为止
      if(pid)
        {
          printf("子进程
    ");
          sleep(1);
        
        }
      else
        {
          printf("父进程
    ");
          sleep(1);
        }return 0;
    }

    程序运行结果:子进程  或者   父进程

           父进程            子进程

      从进程并发执行来看,2种情况都有可能,因为父子进程没有同步机制,所以父进程与子进程的输出内容会叠加在一起,输出次序带有随机性。

      

    下面我们继续对Linux中父子进程对程序的共享与私有部分

    (1)父进程创建子进程后,父子进程各自分支中的部分规个自私有,其余部分(包括创建前和分支结束后的程序段)都为父子进程共享。先面看个例子:

    #include<stdio.h>
    #include<unistd.h>
    int main()
    {
      int p;
      putchar('X');
      while((p=fork())==-1);
      if(p==0)
        {
          putchar('B');
        }
      else
        putchar('A');
      putchar('Y');
      return 0;
    }

    运行结果:XAYXBY或XBYXAY

    (2)如果子进程在其分支结束处使用exit()系统调用来终止自身的执行,则不会在共享其后的程序段。

    (3)对于父子进程不共享的程序段,它们都有各自不同的进程映像,在自己的私有存储空间对数据进行修改不会影响到对方。

    #include<stdio.h>
    #include<unistd.h>
    int main()
    {
      int p;
      int x=1;
      while((p=fork())==-1);
      if(p==0)
        {
          x=9;
          printf("child:x=%d
    ",x);
        }
      else
        printf("parent:x=%d
    ",x);
      return 0;
    }

    运行结果:child:x=9

         parent:x=1

    Linux进程树

      如果一个程序中使用了多个fork()调用,而且每次都不对返回值加以判断,不分析父子进程各自的程序空间,则后面的fork()调用为父子进程所共享,即父子进程返回时都会执行,从而使得家族的进程关系变得复杂。

    #include<stdio.h>
    #include<unistd.h>
    int main()
    {
      fork();
      fork();
      fork();
      putchar('A');
      return 0;
    }

    运行结果:AAAAAAAA

    家族树图稍后上传。。

      先面我们在进一步看fork()&&fork()||fork():

    此处涉及到逻辑运算符运行的机制和对fork()的更深层次了解与认识。其实此式新创建进程4个,下面来分析下:

    A&&B 如果A=0,则就没必要执行B了,如果A!=0,则就执行B;

    A||B 如果A=0则就执行B,如果A!=0则就不用执行B了。

      由此可见fork()&&fork()||fork()创建了4新进程,同理,类此问题迎刃而解。。。

  • 相关阅读:
    设计一个移动应用的本地缓存机制
    LeetCode 15
    POJ 2411
    Mahout构建图书推荐系统【一起学Mahout】
    firefox篇
    zTree实现删除树节点
    Tomcat与Servlet工作流程
    cocos2d 重写顶点着色语言
    将HTML格式的String转化为HTMLElement
    JQuery总结
  • 原文地址:https://www.cnblogs.com/czx1/p/6051695.html
Copyright © 2020-2023  润新知