• Linux------创建和终止进程


    创建进程:

    Linux创建两个步骤的新处理:fork()和exec().其中fork创建当前进程的能力(父进程)副本,那个孩子。父子进程只有PID不同。在这之后,该系统具有两个进程,运行相同的操作。父进程的内容将被复制。可是在Linux中运用了一种写时复写(copy on write)技术。使进程的创建更为高效。接下来exec将读取可运行文件加载地址空间中运行。这样一个进程就创建好啦!

    当中fork系统调用的入口点为sys_fork,该函数和体系结构有关,任务是从处理器的寄存器中提取由用户空间提供的信息。而且调用与体系结构无关的do_fork()函数,进行进程复制。

    然后do_fork主要进行下面几项工作,进行进程生成的实际工作:

    1.调用copy_process复制进程。

    2.获取新进程的PID

    3.用wake_up_new_taskhuanxing唤醒子进程,即将它的task_struct加入到调度器队列中,但这并不意味着它能够马上运行。而是调度器此时能够选择它运行。


    当中进程的复制又包含下面几个步骤:

    1.检查各种标识,类似于CLONE_FS(与父进程共享文件系统)等待,有些标识的组合是没有意义的,所以须要检查

    2.调用dup_task_struct创建父进程task_struct的副本。父子进程的task_struct进程仅仅有核心栈态这个成员不同

    3.检查资源限制,由于每一个用户能拥有的进程数是有限的,超过则要放弃创建进

    4.调用接口函数sched_fork,以便使调度器对新进程进行设置。防止内核的其它不论什么部分在进程设置完毕前调度进程

    5.调用很多类似于copy_xyz的例程,复制和共享内核子系统的各种资源

    6.设置各个ID和进程关系

    这样整个进程就复制结束啦!


    exec()的实现,即用新代码取代旧代码。可启动新程序。

    该系统调用的入口点是和体系结构相关的sys_execve函数。可是该函数非常快将工作交给与系统结构无关的do_execve例程。该例程主要进行下面几个工作:

    1.打开可运行文件

    2.调用bprm_init来处理若干管理性事务:生成mm_alloc管理进程地址空间。init_new_context初始化该实例。__bprm_mm_init建立初始的栈

    3.调用prepare_binprm提供父进程的一些相关值

    4.复制环境和參数数组内容

    5.调用search_binary_handler,在do_execve结束时查找一种适当的二进制格式,用于所要运行的文件。而二进制格式处理程序用于将新程序的数据载入到旧的地址空间中

    这样。一个新的程序就開始运行啦!


    进程的终结:

    进程要终结的时候会调用exit()函数,只是和前面一样,终于都还是通过调用do_exit()这个函数来结束进程的。

    简单的说。就是将各个引用计数器减一。若有计数器归0。则释放对应的内存。

    然后调用exit_notify()告知父进程为子进程找养父,并把进程状态设置为EXIT_ZOMBIE.最后调用schedule()切换到其它进程。

    自此该进程不会被再次调用。此时该进程占用的内存仅为内存栈。thread_info和task_struct。

    当父进程检測到僵尸进程提供的信息之后。将进程所持有的剩余内存释放。至此进程终结。



    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    资源链接
    Node.js—学习
    Node.js—基本知识
    创建服务器证书命令
    解决:Could not load type 'System.ServiceModel.Activation.HttpModule' from assemb
    应用框架的设计与实现——.NET平台(10 授权服务.CodeAccessSecurityAttribute)
    .NET 实现自定义ContextUser的Identity和Principal实现自定义用户信息,权限验证。
    MS对WCF配置中security节点的解释
    Makecert.exe(证书创建工具)
    JAVA操作Mysql数据库
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4629795.html
Copyright © 2020-2023  润新知