填空题
- Linux的设备驱动分为 _____三类,串口是什么类型设备__?
答案: 字符、块、网络;字符。
需要说明的是,现实生活中的问题没有绝对,字符、块、网络更多是从用户的使用层面上来说的,但是Linux的很多驱动根本没有用户的使用层面,比如USB控制器、I2C控制器驱动等,他们更多的是给USB外设、I2C外设提供内核空间的传输接口。再比如针对Flash的MTD子系统,也本身不能归纳为字符、块还是网络。MTD既有字符层面的接口,但是更多的是MTD层面的read page、write page、read oob, write oob,erase block这样的提供给yaffs2, jffs2等文件系统的接口。当然MTD也可以转block。
我们绝对不能孤立和钻牛角尖地去一定得出一个不是此就是彼的结论。
2.下面的程序,在Ubuntu PC的terminal运行,打印几个hello__
main()
{
fork();
printf("hello\n");
fork();
printf("hello\n");
while(1);
}
答案: 6个hello。
第一次fork后,出现2个进程执行第一个printf,之后2个进程又执行了fork,这个时候有4个进程执行第2个printf。进程tree关系如下:
3 . 用>=,>, =, <, <= 连接进程的如下4个内存描述形式,分析它们之间的大小关系:
VSS__ RSS
PSSRSS
USSPSS
答案: vss>=rss>=pss>=uss
理解一个进程的内存消耗的时候,要理解vss,rss,pss,uss这4个基本概念。它们的解释分别为:
VSS- Virtual Set Size 虚拟耗用内存
RSS- Resident Set Size 实际使用物理内存
PSS- Proportional Set Size 比例化后实际使用的物理内存
USS- Unique Set Size 进程独自占用的物理内存
下面的一幅图上有3个进程,pid为1044的 bash、pid为1045的 bash和pid为1054的 cat。每个进程透过自己的页表,把虚拟地址空间指向内存条上面的物理地址,每次切换一个进程,即切换一份独特的页表。
仅从此图而言,进程1044的vss和rss分别是:
vss= "1"+"2"+"3"
rss= "4"+"5"+"6"
但是是不是“4"+"5"+"6”就是1044这个进程真实耗费的内存呢?这显然也是不准确的,因为"4"明显被3个进程指向,"5"明显被2个进程指向,坏事是大家一起干的,不能1044一个人背黑锅。这个时候,就衍生出了一个pss(按比例计算的驻留内存)的概念,仅从这一幅图而言,进程1044的pss为:
rss= "4"/3 +"5"/2 +"6"
最后,还有进程1044独占且驻留的内存uss(Unique Set Size ),仅从此图而言,
Uss = "6"。
4 . 下面这个程序,三次打印的data分别是, , __。
int data = 10;
int child_process()
{
printf("Child process %d, data%d\n",getpid(),data);
data = 20;
printf("Child process %d, data%d\n",getpid(),data);
_exit(0);
}
int main(int argc,char* argv[])
{
if(vfork()==0) {
child_process();
}
else{
sleep(1);
printf("Parent process %d,data %d\n",getpid(), data);
}
}
答案: 10, 20,20
本题属于送分题。既然是vfork,子进程会在vfork后将自己的MM直接暂时指向父进程。
本题若将vfork改为fork,答案则为10, 20, 10。因为fork,会执行内存的“写时拷贝”
5 . 请描述内核代码如下三种编译方式的含义
[] ____
[*] __
[M] ___
答案: 不编译,编译进kerne的image,编译为module。送分题。
6 . gdb设置断点的指令是__,单步n和s的区别是____
答案: b, n单步会跳过函数,s单步会进入函数
7 . 下面一段python程序:
hello.py
print "Hello World! Love, Python"
echo 3 > /proc/sys/vm/drop_caches后,第2次运行比第一次运行快的原因是?
答案: 下面的测试可以显示第二次比第一次快的原因。
$ sudo sh -c ‘echo 3 > /proc/sys/vm/drop_caches‘
第一次运行:
$ \time -v python hello.py
Hello World! Love, Python
Command being timed: "python hello.py"
...
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.19
...
Major (requiring I/O) page faults: 29
Minor (reclaiming a frame) page faults: 546
Voluntary context switches: 122
Involuntary context switches: 34
Swaps: 0
File system inputs: 9920
...
第二次运行:
$ \time -v python hello.py
Hello World! Love, Python
Command being timed: "python hello.py"
...
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.01
...
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 552
Voluntary context switches: 1
Involuntary context switches: 8
Swaps: 0
File system inputs: 0
File system outputs: 0
...
第2次运行的速度比第一次快了很多倍,是因为第2次里面大量的major page fault和file读取没有了。第一次的运行导致I/O在内存的page cache的大量命中。
8 . 请用公式描述下图free命令中数字的关系
a = ___ + ____
g = b - ____ - _____
h = c + ____ + _____
答案: a= b+c; g= b- e -f; h =c +e +f; 送分题。
第二行的used是第一行used减去两类page cache(buffers和cached);第二行的free是第一行的free加上两类page cache。
buffers是指用来给块设备做的page cache大小(比如/dev/sda1);cached是来给文件系统里面文件做的page cache大小(比如/usr/local/xxx/1.jpg)。
问答题
- 描述内核atomic, spinlock, mutex这三个锁分别的实用场景和主要区别
答案:atomic针对的是一个整数,可以用于中断、软中断、进程上下文。但是由于现实生活中,一个整数独立与别人无关的场景并不特别多见,所以atomic用地并没有想象地那么多。比如下面一个结构体
struct a
{
int a1;
int a2;
int a3;
};
尽管a1, a2, a3都是int,但是并不意味着可以用atomic单独操作a1, a2, a3,因为他们之间经常彼此交织,很可能应该被共同加lock,采用spinlock或mutex。
spinlock针对一个区间(critical section),spinlock锁住的区间不能睡眠,因此,spinlock也是中断、软中断、进程上下文到处都可以用。spinlock在核内会关闭scheduler,多核下核间则自旋(核A中断、软中断、进程拿到后,核B中断、软中断、进程想拿,核B自旋)。一般情况下,spinlock锁住的区间要短,要不睡眠。
mutex锁住的区间可能睡眠,当一个进程拿不到mutex的时候,也会放弃CPU进入睡眠状态,直至目前占有mutex的进程释放mutex将其唤醒。mutex锁住的区间可能睡眠,mutex拿不到的时候也会自身进程睡眠,因此mutex一般只能用于进程上下文,不适合中断、软中断、锁住本核调度器的spinlock区间内。
2 . 论述Linux设备驱动模型里面,总线、设备和驱动三者各自的作用及关系。
答案:
点击:《Linux总线、设备、驱动模型》直播PPT分享
点击:《让天堂的归天堂,让尘土的归尘土——谈Linux的总线、设备、驱动模型》
对答案有异议,想留言争辩答案?