面经总结-Linux

1.CFS进程调度算法

使用nice值作为衡量时间片大小的标准,-19-20,值越小,优先级越高。
每个可运行的任务都放在rb-tree上。虚拟运行时间越短,那么nice值就越小,就越在红黑树的左侧,也就是优先级最高的地方。

2.Linux中的锁机制

各种锁机制之间的区别在于,当锁已经被其他线程持有,因而不可用时的表现
锁看起来只是把临界区的大小缩小到了具体的代码段,还是有可能竞争。但是锁本身是原子操作,这点就保证了不会发生竞争。

3.Linux中的中断

首先中断分为上下中断。区别在于上中断是必须立刻执行的,一般是响应中断信号。下中断可以在等待一个系统调用、一个异常、一个中断后再处理。
下中断实现的三种方式:tasklet,软中断,等待队列。
tasklet是基于软中断实现的,不同的是tasklet是可以保证两个中断索引号相同的tasklet不能同时执行。但是用软中断实现都有一个缺点:那就是处于中断上下文,不能睡眠。
为什么中断上下文不能睡眠就是因为,中断并不是系统调度的,你无法用一个信号来唤醒它。而且也无法切换上下文
Linux是以进程为调度单位的,调度器只看到进程内核栈,而看不到中断栈。在独立中断栈的模式下,如果linux内核在中断路径内发生了调度(从技术上讲,睡眠和调度是一个意思),那么linux将无法找到“回家的路”,未执行完的中断处理代码将再也无法获得执行机会。
等待队列是通过内核实现的,比较慢,但可以睡眠。

4.零拷贝 zero copy

背景:比如现在要读一块静态的内容A,并展示给用户。那么就是从内存buf中读数据,然后通过socket发到客户端。这里有多少次拷贝呢?整个数据过程是从磁盘中把数据读到内存,再从内存中把数据读到网卡中。
一共是4次拷贝,4次用户/内核切换
首先调用read,因为是系统调用,所以要进入内核态
请求的数据A再磁盘中,首先进入内核态,系统调用从磁盘中将A移动到内存中。
从内核态buffer中把数据拷贝到用户态buffer
然后调用write
切换到内核态,将数据拷贝到内核态buffer中
将数据再拷贝到网卡中,发送出去。
mmap是零拷贝的实现基础方式
内核/用户态还是4次切换,但是省去了:内核缓冲区到用户缓冲区的拷贝
zerocopy实现后,只需要3次拷贝,2次用户/内核的切换 Linux中sendfile实现
首先从用户态切换到内核态
磁盘把数据拷贝到内核缓冲区
内核缓冲区把数据拷贝到socket缓冲区
socket缓冲区拷到网卡中
切回用户态
改进:内核不拷贝到socket,只需要记录偏移量和基址在socket缓冲中,然后直接拷贝到网卡中就可以了(sendfile + DMA收集)。

5.Linux进程调度策略

O(n)
分时间片
在每个时间片开始时,计算就绪进程的优先级,从优先级高的开始运行,不会被抢占,没用完的时间片留给下个进程。
每次使用时间片之前,都要检查所有就绪队列的优先级
O(1)
空间换时间,用了两种队列,一种活跃队列,存储未分配时间片的进程;一种过期队列,存已经用过时间片的进程。两者分别都有0-139个队列数,分别对应的是它们自己的优先级,一开始都在活跃队列中。
每次直接从活跃队列中取就可以了,用完的丢到过期队列
缺点在于运行顺序和时间过于依赖优先级。
CFS完全公平调度
增加一个虚拟运行时间(运行过多久)这个属性,每次选择的是虚拟运行时间最少的进程。
使用nice值作为衡量时间片大小的标准,-19-20,值越小,优先级越高。每个可运行的任务都放在rb-tree上。虚拟运行时间越短,那么nice值就越小,就越在红黑树的左侧,也就是优先级最高的地方。

6.mmap的实现机制

mmap的概念说是将内存映射到每个进程的地址空间中
那么映射是什么?就是占有进程的一部分地址空间,但是并不会实际地把物理内存拷贝过去。只是建立了逻辑地址与物理地址的连接。
那么总得有第一份拷贝把?
这个点的实现方式其实和写时复制有点类似。
现在把一个内存映射到进程中了,但是其实还没有使用这块共享内存,这块内存还放在磁盘中
第一个进程使用这块内存了,然后因为并不存在实际的物理页,发生缺页中断,这时候把该内存拷贝到内核的高速缓存区,然后将进程的页表更新,指向这页,就可以正常使用了。
其他进程要用的时候,只需要改页表就够了。

#互联网求职##面经#
全部评论
马了,感谢总结
1 回复 分享
发布于 2021-08-01 21:59

相关推荐

2 34 评论
分享
牛客网
牛客企业服务