do_fork()
:copy_process()
do_timer()
wake_up_process()
:进程由睡眠状态转为RUNNING
状态sys_sched_yield()
sched_setscheduler()
:Linux
内核中CFS
调度器有一个计算虚拟时间的API函数(calc_delta_fair()
),公式如下:
v r u n t i m e = d e l t a _ e x e c ∗ n i c e _ 0 _ w e i g h t w e i g h t vruntime = \frac {delta\_exec * nice\_0\_weight}{weight} vruntime=weightdelta_exec∗nice_0_weight
v r u n t i m e vruntime vruntime表示进程虚拟运行时间; d e l t a _ e x e c delta\_exec delta_exec表示实际运行时间; n i c e _ 0 _ w e i g h t nice\_0\_weight nice_0_weight表示nice
值为0的进程的权重值, w e i g h t weight weight表示此进程权重值。
当进程的nice
值不等于0
时,虚拟时间和真实时间不一样。nice
值小的进程优先级高,虚拟时间比真实时间跑慢一些;nice
值大的进程优先级低,虚拟时间比真实时间跑快一些。为方便记忆,Linux
内核约定nice
值为0
的进程的权重值为1024
。内核预先计算好表如下:
kernel/sched.c
static const int prio_to_weight[40] = {
/* -20 */ 88761, 71755, 56483, 46273, 36291,
/* -15 */ 29154, 23254, 18705, 14949, 11916,
/* -10 */ 9548, 7620, 6100, 4904, 3906,
/* -5 */ 3121, 2501, 1991, 1586, 1277,
/* 0 */ 1024, 820, 655, 526, 423,
/* 5 */ 335, 272, 215, 172, 137,
/* 10 */ 110, 87, 70, 56, 45,
/* 15 */ 36, 29, 23, 18, 15,
};
比如技术面试:假设某个进程nice
值为1
,其权重值为820
,delta_exec
=12ms
,代入公式计算:vruntime=(12*1024)/820= 15
。
vruntme
的值越小,证明占用cpu
时间越少(或者说权重越大),此时则优先运行,所使用红黑树是根据全部进程vruntime
来组织的,树最左下角的节点就是vruntime
最小的节点,是需要最先执行的节点;随着进程的执行,vruntime
是不停的变化,就需要动态调整红黑树。由于红黑树本身的算法特点,动态调整比链表快,这是为什么选择CFS
根本原因。CFS
算法没有时间片,而是根据实际运行时间和虚拟运行时间来对任务进行排序,从而选择调度。
主要有哪几种内核锁?Linux 内核的同步机制是什么?
Linux 中的用户模式和内核模式是什么含义?
怎么申请大块内存?vmalloc 和 kmalloc 有什么区别?
进程间通信主要有哪几种方式?
伙伴系统申请内存的函数有哪些?
通过 slab 分配器申请内存的函数有哪些?
Linux 的内核空间和用户空间如何划分的?进程地址空间布局图?
vmalloc() 申请内存有什么特点?
用户程序使用 malloc() 申请的内存空间在什么范围?
在支持并使能 MMU 的系统中,Linux 内核和用于程序分别运行在物理地址模式还是虚拟地址模式?
ARM 处理器是通过几级页表进行存储空间映射的?
Linux 是通过什么组件来实现支持多种文件系统的?
Linux虚拟文件系统的关键数据结构有哪些?(至少写出4个)
对文件系统的操作函数保存在哪个数据结构中?
Linux 中的文件包括哪些?
创建进程的系统调用有哪些?
调用 schedule() 进行进程切换的方式有几种?
Linux 调度程序是根据进程的动态优先级还是静态优先级来调度进程的?
进程调度的核心数据结构是哪个?
如何加载、卸载一个模块?
模块和应用程序分别运行在什么空间?
Linux 中的浮点运算由应用程序实现还是内核实现?
模块程序能否使用可链接的库函数?
TLB 中缓存的是什么内容
Linux 中有哪几种设备?
字符设备驱动程序的关键数据结构是哪个?
设备驱动程序包括哪些功能函数?
如何唯一标识一个设备?
Linux 通过什么方式实现系统调用?
Linux 软中断和工作队列的作用是什么?
下面是面试题的答案:
自旋锁:spin_lock 忙等,中断中使用
信号量:semxxx down/up write/read
mutex:初始化为1的信号量
读写锁,RCU(read-copy update)
2. Linux 中的用户模式和内核模式是什么含义?
cpu mode,用户模式只能通过系统调用操作硬件资源,内核模式可以直接操作硬件资源
3. 怎么申请大块内存?vmalloc 和 kmalloc 有什么区别?
vmalloc 用于申请大块内存,虚拟地址连续,物理地址不一定连续,不能直接用于DMA,在进程地址空间有专门的一块。
kmalloc 用于申请小内存,由 slab 管理实现,一般至少小于4KB(page)。不能申请大于128K的数据。物理地址和虚拟地址都连续,可用于DMA操作。
4. 进程间通信主要有哪几种方式?
管道:两个进程需要有共同的祖先,pipe/popen
命名管道:两个进程可以无关
信号
消息队列
共享内存
信号量
套接字
Android:binder/ashmem
5. 伙伴系统申请内存的函数有哪些?
alloc_page(gfp_mask, order)
__get_free_pages(gfp_mask, order)
6. 通过 slab 分配器申请内存的函数有哪些?
自己构造对象:kmem_cache_create/kmem_cache_alloc
普通匿名内存申请:kmalloc
7. Linux 的内核空间和用户空间如何划分的?进程地址空间布局图?
32位可配置3G/1G, 2G/2G,一般是两级页表
64位可配置几级页表,一般可选3级/4级页表,256G/256G,或512T/512T
8. vmalloc() 申请内存有什么特点?
申请大块内存,虚拟地址连续,物理地址不一定连续,不能直接用于DMA。对于释放函数 vfree()。
9. 用户程序使用 malloc() 申请的内存空间在什么范围?
stack 和 heap 中间。小于128M的通过brk申请,大于的通过 mmap 申请。
10. 在支持并使能 MMU 的系统中,Linux 内核和用于程序分别运行在物理地址模式还是虚拟地址模式?
都运行在虚拟地址模式,页表转换对应由硬件单元MMU完成。
11. ARM 处理器是通过几级页表进行存储空间映射的?
两级页表,PGD和PTE
12. Linux 是通过什么组件来实现支持多种文件系统的?
VFS(virtual file system)
13. Linux虚拟文件系统的关键数据结构有哪些?(至少写出4个)
super_block超级块
inode索引节点
dentry目录项
file文件
14. 对文件系统的操作函数保存在哪个数据结构中?
struct file_operations
15. Linux 中的文件包括哪些?
可执行文件,普通文件,目录文件,链接文件,设备文件,管道文件
16. 创建进程的系统调用有哪些?
clone, fork, vfork
17. 调用 schedule() 进行进程切换的方式有几种?
do_fork/do_timer/wake_up_process/setscheduler/sys_sched_yield
18. Linux 调度程序是根据进程的动态优先级还是静态优先级来调度进程的?
cfs 会计算虚拟时间,还有一个计算出来的优先级。
实时进程根据xx
19. 进程调度的核心数据结构是哪个?
struct runqueue
20. 如何加载、卸载一个模块?
ismod, rmmod
21. 模块和应用程序分别运行在什么空间?
模块运行在内核空间,应用程序运行在用户空间
22. Linux 中的浮点运算由应用程序实现还是内核实现?
由应用程序实现,对应的数学库函数。
23. 模块程序能否使用可链接的库函数?
module 运行在内核空间,不能链接库函数。
24. TLB 中缓存的是什么内容
translation lookaside buffer, 也叫快表,用作页表缓冲。记录虚拟地址和物理地址的对应关系,用于加快地址转换。
25. Linux 中有哪几种设备?
字符设备和块设备
26. 字符设备驱动程序的关键数据结构是哪个?
struct cdev: kobject
cdev_alloc()
cdev_add()
27. 设备驱动程序包括哪些功能函数?
open/read/write/ioctl/release/llseek
28. 如何唯一标识一个设备?
主设备号和次设备号。dev_t,12位表示主设备号,20位表示次设备号。
MKDEV(int major, int minor)用于生产一个 dev_t 类型的对象。
29. Linux 通过什么方式实现系统调用?
软件中断。系统调用编号,异常处理程序
30. Linux 软中断和工作队列的作用是什么?
软中断:不可睡眠阻塞,处于中断上下文,不能进程切换,不能被自己打断。
工作队列:处理进程上下文中,可以睡眠阻塞。