linux进程的深入理解与分析

linux进程的深入理解与分析

ID:42625229

大小:78.09 KB

页数:19页

时间:2019-09-19

linux进程的深入理解与分析_第1页
linux进程的深入理解与分析_第2页
linux进程的深入理解与分析_第3页
linux进程的深入理解与分析_第4页
linux进程的深入理解与分析_第5页
资源描述:

《linux进程的深入理解与分析》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、linux进程的深入理解与分析    进程是程序的一次执行过程。用剧本和演出来类比,程序相当于剧本,而进程则相当于剧本的一次演出,舞台、灯光则相当于进程的运行环境。进程的堆栈   每个进程都有自己的堆栈,内核在创建一个新的进程时,在创建进程控制块task_struct的同时,也为进程创建堆栈。一个进程有2个堆栈:用户堆栈和系统堆栈;用户堆栈的空间指向用户地址空间,内核堆栈的空间指向内核地址空间。当进程在用户态运行时,CPU堆栈指针寄存器指向用户堆栈地址,使用用户堆栈;当进程运行在内核态时,CPU堆栈指针寄存

2、器指向的是内核栈空间地址,使用的是内核栈。进程用户栈和内核栈之间的切换    当进程由于中断或系统调用从用户态转换到内核态时,进程所使用的栈也要从用户栈切换到内核栈。系统调用实质就是通过指令产生中断,称为软中断。进程因为中断(软中断或硬件产生中断),使得CPU切换到特权工作模式,此时进程陷入内核态,进程进入内核态后,首先把用户态的堆栈地址保存在内核堆栈中,然后设置堆栈指针寄存器的地址为内核栈地址,这样就完成了用户栈向内核栈的切换。    当进程从内核态切换到用户态时,最后把保存在内核栈中的用户栈地址恢复到C

3、PU栈指针寄存器即可,这样就完成了内核栈向用户栈的切换。    这里要理解一下内核堆栈。前面我们讲到,进程从用户态进入内核态时,需要在内核栈中保存用户栈的地址。那么进入内核态时,从哪里获得内核栈的栈指针呢?   要解决这个问题,先要理解从用户态刚切换到内核态以后,进程的内核栈总是空的。这点很好理解,当进程在用户空间运行时,使用的是用户栈;当进程在内核态运行时,内核栈中保存进程在内核态运行的相关信息,但是当进程完成了内核态的运行,重新回到用户态时,此时内核栈中保存的信息全部恢复,也就是说,进程在内核态中的代码

4、执行完成回到用户态时,内核栈是空的。   理解了从用户态刚切换到内核态以后,进程的内核栈总是空的,那刚才这个问题就很好理解了,因为内核栈是空的,那当进程从用户态切换到内核态后,把内核栈的栈顶地址设置给CPU的栈指针寄存器就可以了。   ArmLinux内核栈定义如下(可能现在的版本有所改变,但不妨碍我们对内核栈的理解),在include/linux/sched.h中定义了如下一个联合结构:unionthread_union{structthread_infothread_info;unsignedlongs

5、tack[THREAD_SIZE/sizeof(long)];};19/19从这个结构可以看出,内核栈占8KB的内存区。实际上,进程的task_struct结构所占的内存是由内核动态分配的,更确切地说,内核根本不给task_struct分配内存,而仅仅给内核栈分配8K的内存,并把其中的一部分给task_struct使用。   这样内核栈的起始地址就是uniontask_union变量的地址+8K 字节的长度。例如:我们动态分配一个uniontask_union类型的变量如下:unsignedchar*gta

6、skkernelstack;gtaskkernelstack=kmalloc(sizeof(uniontask_union));    那么该进程每次进入内核态时,内核栈的起始地址均为:(unsignedchar*)gtaskkernelstack+8096 进程上下文    进程切换现场称为进程上下文(context),包含了一个进程所具有的全部信息,一般包括:进程控制块(ProcessControlBlock,PCB)、有关程序段和相应的数据集。 进程控制块PCB(任务控制块)    进程控制块是进程在

7、内存中的静态存在方式,Linux内核中用structtask_struct表示一个进程(相当于进程的人事档案)。进程的静态描述必须保证一个进程在获得CPU并重新进入运行态时,能够精确的接着上次运行的位置继续进行,相关的程序段,数据以及CPU现场信息必须保存。处理器现场信息主要包括处理器内部寄存器和堆栈等基本数据。进程控制块一般可以分为进程描述信息、进程控制信息,进程相关的资源信息和CPU现场保护机构。 进程的切换当一个进程的时间片到时,进程需要让出CPU给其他进程运行,内核需要进行进程切换。Linux 的进

8、程切换是通过调用函数进程切换函数schedule来实现的。进程切换主要分为2个步骤:1. 调用switch_mm()函数进行进程页表的切换;2. 调用 switch_to() 函数进行 CPU寄存器切换;  __switch_to定义在arch/arm/kernel目录下的entry-armv.S 文件中,源码如下:ENTRY(__switch_to)UNWIND(.fnstart)UNWIND(.cantunw

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。