zoukankan      html  css  js  c++  java
  • fork(),clone()系统调用进行进程创建的过程

    首先它们最终都调用了内核里的do_fork()函数,然后完成了下述操作

    1、调用alloc_task_struct()函数申请8KB的内核栈内存空间,供新建进程使用;

    2、让指针指向父进程的PCB,然后将父进程的PCB内容拷贝到给新进程分配的PCB中去,此时父子进程完全相同,当然拷贝内容包括了:指令,变量值,程序调用栈,缓存区,环境变量等等,而此时若搭配一些有缓存的语句,就会出现意想不到的结果了,这是后话。

    3、检查创建该进程后,是否越界,即该用户所拥有的进程数目是否超过了给它分配的资源的限制;

    4、然后就是建立新创建的子进程的新的,独有资源,并且通知内核此进程已经诞生。

    5、设置子进程的状态,确保它不会马上投入运行;

    6、调用get_pid()为新子进程获取一个有效的PID;

    7、进一步更新从父进程PCB继承来的其他所有不同地方,例如亲属关系,状态信息等;

    8、根据传递给clone()的参数标志,拷贝或共享打开的文件,文件系统信息,信号处理函数,进程的虚拟地址空间等。若进程包含线程,则所有线程共享这些资源,否则各进程对这些资源进行拷贝;

    9、把新的PCB插入到进程链表,确保进程间的亲属关系;

    10、把新的PCB插入到pidhash哈希表;

    11、把子进程的状态设置为TASK_RUNNING,并调用weak_up_process()把子进程插入到运行队列中;

    12、让父子进程平分剩余时间片;

    13、返回子进程PID,并由用户态下的父进程读取。

    注意:子进程已经就绪,但还得看调度程序什么时候将CPU交给它,它才能真正开始运行。

    同时,操作系统内核会有意地选择让子进程先执行,然后才是父进程。这是因为一般子进程会立即调用exec()以读取可执行文件并将其载入进程地址空间开始运行,来避免写时复制的额外开销。

  • 相关阅读:
    SQList基础+ListView基本使用
    Git本地上传口令
    记住用户名和登录密码+虚拟机没有root权限解决办法
    API+gir上传错误解决办法
    界面跳转+信息传递+AS中如何将ADV转移到其他盘中
    界面跳转
    Android学习——ListView
    开课第一周周总结
    体温上报APP——班级统计
    体温上报APP——打印
  • 原文地址:https://www.cnblogs.com/ancient/p/3210805.html
Copyright © 2011-2022 走看看