linux进程的地址空间,核心栈,用户栈,内核线程

地址空间:

32位linux系统上,进程的地址空间为4G,包括1G的内核地址空间,和3G的用户地址空间。

内核栈:

进程控制块task_struct中保存了2个page大小的信息。

为什么每一个进程都是用各自的内核栈呢?

引用(http://hi.baidu.com/iruler/blog/item/0c3363f377ccc5c90a46e023.html)“

假设某个进程通过系统调用运行在内核态(使用这个全局内核堆栈),此时如果被抢占,发生一次切换,另一个进程开始运行,如果这个当前进程又通过系统调用陷入内核,那么这个进程也将使用这个全局内核堆栈,这样的话就把以前那个进程的内核空间堆栈给破坏了。
而如果进程使用独立的内核栈,就避免了这种情况的发生

内核线程:

拥有自己独立内核栈的调度单元,可以参与调度,在内核空间执行。

用户栈:

每一个线程有一个用户栈,由ss和esp指向。

===================================================

进程1                                进程2

内核代码区      kcode (0xc0001000)        
 kcode (0xc0001000)

内核栈区          kstack(0xc000F000)          kstack(0xc001F000)

内核栈区          kstack(0xc000D000)          kstack(0xc001D000)

...

内核数据区      kdata  (0xc0003000)          kdata  (0xc0003000)

---------------------------------------------------------------------------------------------

用户代码区      ucode  (0x70001000)        ucode (0x70001000)

用户栈区          ustack (0x7000F000)        ustack (0x7000F000)

用户栈区          ustack (0x7000D000)        ustack (0x7000D000)

...

用户数据区      udata   (0x70003000)        udata  (0x70003000)

===================================================

合理的解释:

内核1G空间的映射页表(256个entries*4M)只有一份,n个进程共享(都复制了一份在自己的进程页表内, 256个内核的entries+768个用户空间的entries, 总共1024个entries,假定使用4M页面,并且一开始就全都分配好)。

每个进程用户空间的这些entries各不相同,比如说,同样的0x70001000虚拟地址, 进程1指向物理内存0x2000, 而进程2指向0x1000。

每个线程对应的内核栈的虚拟地址不重叠。

thread1's kernel stack  = 0f000,

thread2's
kernel stack  = 0d000,

thread3's
kernel stack  = 1f000,

thread4's
kernel stack  = 1d000

...

思考1:

如果内核栈不是预先分配好的(分
配的意思是指"在内核空间中分出一段一段不重叠空间作为各个线程的栈", e.g. kmalloc调用),那么步入内核态的时候,
压栈,发生缺页异常,必须对内核栈占用的这个页进行换页,而换页历程的调用必然涉及参数的压栈出栈,而这个时候内核栈没有就绪,异常发生嵌套,系统出错!

思考2:

在内核里面做kmalloc是可以的,添加一个entries,关联一块物理内存,ok可以用了。

思考3:

如果希望进程共享某一个虚拟内存地址0x80001000的数据, 那么在需要共享的进程p1,p2的页表中添加1个entries(0x80001000->0x3000)。

另外内核是天然的共享对象,所以才在每一个进程中页表中设置内核空间页表的一份拷贝。

如果有个家伙特立独行,创建n个关于内核空间的页表,指向n个物理内存块,那么他就需要再在这n个物理内存中"铺设"n分内核代码和数据的副本(真是自找麻烦)。

思考4:

内核栈确实不适合共享(一个特殊的内存区域)。怎么办?像用户空间栈一样固定在某一个虚拟地址,安插页表项entries指向不同的物理内存?显然不行! 只有一个办法,在内核空间内分配n个不重叠的空间出来。

思考5:

内核步入的时候最初的“内核栈”并不是真正的内核栈,这个栈是全局的,每个cpu一个,是过渡到真正的内核栈使用的。(http://bbs.pediy.com/archive/index.php?t-87518.html)

思考6:

独立内核栈的场景, at first 我们分析一下如果共用一个内核栈会出现什么情况,假设有A、B三个进程,A调用系统调用read(1,...)读按键,此时正好又没有按键,
所以A被阻塞在内核,此时内核调度B执行,此时B也调用一个系统调用被阻塞了,而此时按键事件到来,进程A被唤醒,A继续执行。我们想想B进入内核
已经破坏了A进入内核的内核栈,那此时A能正常返回吗?所以从上面分析A、B肯定是拥有各自的内核栈。此内核栈好像是和task_struct以前分配的
一共分配了3个页面,除了task_struct占得内存外,其余的就是内核栈。而在x86上这个栈等指针保存在TSS断的SS0和Esp0中。(http://bbs.chinaunix.net/thread-1930753-1-1.html)

参考资料:

1, 内核栈的使用(http://tech.ddvip.com/2008-09/122095404362368.html)

linux进程的地址空间,核心栈,用户栈,内核线程的更多相关文章

  1. linux进程虚拟地址空间

    转载源 在多任务操作系统中,每个进程都运行在属于自己的内存沙盘中.这个沙盘就是虚拟地址空间(Virtual Address Space),在32位模式下它是一个4GB的内存地址块.在Linux系统中, ...

  2. Linux进程虚拟地址空间管理2

    2017-04-12 前篇文章对Linux进程地址空间的布局以及各个部分的功能做了简要介绍,本文主要对各个部分的具体使用做下简要分析,主要涉及三个方面:1.MMAP文件的映射过程 2.用户 内存的动态 ...

  3. LInux进程虚拟地址空间的管理

    2017-04-07 脱离物理内存的管理,今天咱们来聊聊进程虚拟内存的管理.因为进程直接分配和使用的都是虚拟内存,而物理内存则是有系统“按需”分配给进程,在进程看来,只知道虚拟内存的存在! 前言: 关 ...

  4. linux进程模型总结

    Linux进程通过一个task_struct结构体描述,在linux/sched.h中定义,通过理解该结构,可更清楚的理解linux进程模型.       包含进程所有信息的task_struct数据 ...

  5. Linux进程模型

    ----原文链接:http://www.cnblogs.com/biyeymyhjob/archive/2012/08/01/2617884.html------ Linux进程通过一个task_st ...

  6. Linux下的进程类别(内核线程、轻量级进程和用户进程)--Linux进程的管理与调度(四)

    本文中出现的,内核线程,轻量级进程,用户进程,用户线程等概念,如果不太熟悉, 可以参见 内核线程.轻量级进程.用户线程三种线程概念解惑(线程≠轻量级进程) Linux进程类别 虽然我们在区分Linux ...

  7. Linux内核线程kernel thread详解--Linux进程的管理与调度(十)

    内核线程 为什么需要内核线程 Linux内核可以看作一个服务进程(管理软硬件资源,响应用户进程的种种合理以及不合理的请求). 内核需要多个执行流并行,为了防止可能的阻塞,支持多线程是必要的. 内核线程 ...

  8. Linux进程管理 (篇外)内核线程简要介绍

    关键词:kthread.irq.ksoftirqd.kworker.workqueues 在使用ps查看线程的时候,会有不少[...]名称的线程,这些有别于其它线程,都是内核线程. 其中多数内核线程从 ...

  9. linux内核线程,进程,线程

    http://blog.csdn.net/dyllove98/article/details/8917197 Linux对于内存的管理涉及到非常多的方面,这篇文章首先从对进程虚拟地址空间的管理说起.( ...

随机推荐

  1. 集成环境wamp环境下 memcached的安装

    早就听说过memcached,但是一直没实践过.所有今天有时间就搞了一下,哎废了我一上午才搞定!一上午啊,好丢人.特写记录一下 先说一下我遇到的问题:按照别人教程(还有好多)说的,安装后没有任何的错误 ...

  2. python: 实现sha1小工具

    File1: sha1.py File2: sha1.bat ------------------ File1: sha1.py import hashlib import os,sys def Ca ...

  3. Lucene 3.0

    http://www.cnblogs.com/forfuture1978/archive/2010/02/22/1671487.html http://www.cnblogs.com/jiekzou/ ...

  4. 用开源AOP简化MVVM框架

    本文的前提是知晓基于Xaml开发,本文以WPF为例 一 .简化属性通知事件 普通的属性通知会写一个基于INotifyPropertyChanged接口的类 public class RasieProp ...

  5. SQL效率的几点心得

    这几天一直在写SQL,有时候对比同样效果的SQL语句,可是查询所需要的时间有时候相差很多,下面总结遇到的几个点: 1.between   and 在有些时候自己比较喜欢使用这个语句,因为可以通过把数据 ...

  6. Python默认模块 os和shutil 实用函数

    os.sep 可以取代操作系统特定的路径分隔符.windows下为 '\\' os.name 字符串指示你正在使用的平台.比如对于Windows,它是'nt',而对于Linux/Unix用户,它是 ' ...

  7. Jquery each 的跳出 break continue

    在Jquery each 中 break 是用 return false; continue 是用 return true;

  8. WPF多语言化的实现

    Metro插件系统系列就暂时停一下,这次我们讨论一下WPF的资源本地化实现,主要用到的:CultureInfo,ResourceManger,MarkupExtension,RESX文件,这些都是.N ...

  9. android studio 中设置apk的版本号

    今天在mainfest.xml中设置版本号为2,(代码获取到的版本号无效) android:versionCode="2" android:versionName="2. ...

  10. Python标准库之os模块

    1.删除和重命名文件 import os import string def replace(file, search_for, replace_with): # replace strings in ...