入门Linux Kernel就是看的Robert Love所著的《linux kernel development》和 《linux system programming》,感觉真的是深入浅出娓娓道来。这几天在Quora上看到大神对 Linux Kernel 的一些回答,也是深有启发,特此将一些有意思的问题翻译过来。
(6)当Linux的一个进程占据了100%的CPU时,Linux调度器会做什么?这是不是意味着没有其他进程可以执行了?
在大多数系统上,CPU的使用率都只是一个估计。在Linux上,CPU的使用率 = 1 - idle进程的CPU占有率。如果idle进程在过去1000毫秒里运行了300毫秒,那么系统的CPU使用率就是70%。如果一个进程对CPU的使用率是100%,那么意味着这个进程在过去的N毫秒里运行了N毫秒,而idle进程没有运行过。
那么Linux调度器做了些什么呢?进程的CPU占有率100%已经达到了系统定义的上限。这意味着在Linux调度器选择这个进程运行且这个进程运行完后,Linux调度器又选择这个进程运行,如此重复下去。
那是不是意味着其他进程都不能执行了呢?不。不管目前CPU占有率100%的进程在干什么,一个更高优先级的进程总是可以运行的。而即便是比这个进程优先级低的进程最终也会执行(除非当前进程为实时进程),因为Linux是所有进程共享CPU的。
我认为一个CPU占有率为100%的进程意味着系统当前的运行队列里只有这一个进程。或许吧,除非该进程是实时进程。
同时我认为除非这个进程休眠或者退出,否则idle进程永远不会被调度。对。如果系统有一个任务正在执行,为什么要运行一个什么都不干的idle进程呢?
(7)“内核内存是不可换页(page-able)的”是什么意思?
“内核内存不可换页”是指内核拥有的内存是物理RAM,不可被换页到硬盘(swap分区)上。至于为什么内核内存不可换页,没有什么根本原因。大多数内核,包括Linux内核,都不会对内核内存进行换页操作,因为这样做的好处不足以抵消操作带来的复杂性。
内存仍然是按页划分的,每一页内存用结构体 struct page表示、
(8)干净内存和脏内存有什么区别?
当硬盘上的文件被加载到内存当中后,如果这部分内存的内容被更改了却还没来得及写回硬盘,导致内存中的数据和硬盘上的数据不同步,我们就说这样的内存是脏的。Linux有一种回写(writeback)机制,用来更新硬盘上的数据,从而保证二者同步。
如果硬盘上的数据和加载到内存中的数据是一致的,我们就说这块内存是干净的。
(9)Linux进程间可以共享内存吗?
现代系统共享内存一般都是通过线程来实现的,不过SystemV和POSIX都定义了共享内存的API,因此即便是不相关的进程也可以共享一部分内存。POSIX的API是:
int shm_open (constchar* name,int oflag,mode_t mode);
一次成功的shm_open()调用会返回一个内存区域的文件描述符。这块内存的名字是name,访问模式是oflag,权限是mode(如果是创建一块新的共享内存)。
oflag是和open()系统调用里差不多的标志位,比如有O_RDONLY(内存段只可写)或者O_RDWR(内存段可写可读)。
共享内存的一般形式是首先有一个进程通过shm_open()来创建一块名字为name的共享内存,然后通过ftruncate()来改变这块内存的大小,最后通过mmap()把它映射到自己的内存地址空间。
其他进程则可以通过shm_open()来打开这个名字叫name的共享内存,然后通过mmap()来得到这片共享内存的指针。
(10)Linux内核中高端内存和普通内存有什么区别?
高端内存是指不会永久性映射到内存地址空间的内存。低端内存刚好相反:内存一直会映射到内核的地址空间。
在一个理想的世界中,所有内存都是永久可映射的。但不幸的是,这种情况很难实现。高端内存最常用的例子就是32位intel处理器上使用的PAE(页地址扩展)技术。PAE允许32位的x86架构去寻超过32位的内存地址。在大多数情况下,PAE通过36位的物理地址空间来支持最高64GB的RAM。由于36>32,不是所有的内存都会被映射,这其中的差值就是高端内存。
“高端内存不能被内核映射”是不对的。高端内存可以被内核映射,但是这样做会有一些代价和限制。由于这些代价和限制,再加上Linux内核倾向于使用物理上连续的内存,内核只会在一些特定的场合使用高端内存。
由于用户空间的虚拟地址必须被显示映射,高端内存非常适用于用户空间。因此绝大多数的高端内存都是被用户程序使用的。
(如果你想在Linux内核当中找到高端内存的用法,用grep来查找__GFP_HIGHMEM和GFP_HIGHUSER,这两个标志表示要求分配高端内存。如果没有这些标志,所有的内核内存分配都只会返回低端内存。