从整体上理解进程创建、可执行文件的加载和进程执行以及进程切换

原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/
学号 271

实验环境:实验楼虚拟,机内核版本Linux3.18.6


一. 进程的创建

1.什么是进程,进程有什么状态?

    通俗的讲程序是一个包含可以执行代码的静态的文件。进程是一个开始执行但是还没有结束的程序的实例。当程序被系统调用到内存以后,系统会给程序分配一定的资源(内存,设备等等)然后进行一系列的复杂操作,使程序变成进程以供系统调用。

    进程按照功能可以分为内核进程和用户进程

    在Linux中进程分为五个状态:。

  • task_running:就绪态或者运行态,进程就绪可以运行,但是不一定正在占有CPU
  • task_uniterruptible: 睡眠态,深度睡眠,不响应信号,典型场景是进程获取信号量阻塞
  • task_interruptible:阻睡眠态,但是进程处于浅度睡眠,可以响应信号,一般是进程主动sleep进入的状态
  • task_zobie:僵尸态,进程已退出或者结束,但是父进程还不知道,没有回收时的状态
  • task_stoped:停止,调试状态

 2.进程的结构

    本文以Linux3.18.6内核为基础进行介绍,详细见/linux-3.18.6/include/linux/sched.h

     为了管理进程,OS用PCB(进程描述符)来定义其数据结构在Linux中就是task_struct,由于其定义比较复杂,就选几个比较重要的讲一下:


pid_t pid;//进程ID
volatile long state;//表示进程的当前状态,一共大约有11中,比较常见的见上面的进程状态图
unsigned long flags;  //进程标志:
long priority;  //进程优先级。 Priority的值给出进程每次获取CPU后可使用的时间(按jiffies计)。优先 
                 //级可通过系统调用sys_setpriorty改变(在kernel/sys.c中)。

long counter;  //在轮转法调度时表示进程当前还可运行多久。
unsigned long policy;  //该进程的进程调度策略,可以通过系统调用sys_sched_setscheduler()
void *stack;//进程通过alloc_thread_info函数分配它的内核栈,通过free_thread_info函数释放所分配的 
               //内核栈。 

 3.进程的创建:

    Linux主要提供了fork、vfork和clone三个系统调用来创建一个新进程,在源码中,通过一个系统调用表映射到sys_fork(),sys_vfork(),sys_clone(),再在这三个函数中去调用do_fork()去做具体的创建进程工作。

    其中这三种方式的区别:

1. fork()出来的子进程是父进程的一个拷贝,即,子进程从父进程得到了数据段和堆栈段的拷贝,这些需要分配新的内存;而对于只读的代码段,通常使用共享内存的方式访问;而vfork()则是子进程与父进程共享内存空间, 子进程对虚拟地址空间任何数据的修改同样为父进程所见;clone()则由用户通过参clone_flags 的设置来决定哪些资源共享,哪些资源拷贝。
2. fork()不对父子进程的执行次序进行任何限制,fork()返回后,子进程和父进程都从调用fork函数的下一条语句开始行,但父子进程运行顺序是不定的,它取决于内核的调度算法;而在vfork()调用中,子进程先运行,父进程挂起,直到子进程调用了exec()或exit()之后,父子进程才有可能执行;clone()中由标志CLONE_VFORK来决定子进程在执行时父进程是阻塞还是运行,若没有设置该标志,则父子进程同时运行,设置了该标志,则父进程挂起,直到子进程结束为止。

     简单介绍一下用fork()创建的父子进程的关系


#include <stdio.h>
 

int main(void)
{
    int pid;
    int count2=0;
    int count1=0;
    count1++;
    count2++;
    printf("count1=%d,count2=%d\n",count1,count2);
 
    pid=fork();  //父进程执行了一遍,子进程执行了一遍
    if(pid<0)
        {
        
            fprintf(stderr,"Fork Failed!");
            exit(-1);
     else if(pid=
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值