2009年(49)
分类:
2009-05-25 12:15:14
CHAPTER 3 PROCESS
一
2.6中,内核栈和thread_info一起占用8KB的连续内存空间(2 page frames),这样用ESP就能方便的找到task_struct所在的地址,不用存取内存。thread_info 和task_struct相互指向对方(task_struct存在哪里?)
2.4中,内核栈和task_struct存在一起。
二
2.6中,crurrent是一个宏,而低版本的里面current是一个全局变量。
三
链表中LINUX统一使用list_head这个结构
List_for_each宏用于遍历这个链表.
Wait_queue中,可以同时有exlusive和nonexclusive两种状态,经管这种情况不经常出现。
Sleep_on函数可以将process加入到特定的wait_queue中
Wake_up()函数有多种形式,对应不同的功能。
四
进程资源限制
每个进程都有资源限制,每个进程有如下结构体(当前):current->signal->rlim[]
Struct rlimit{
Unsigned long rlim_cur;
Unsigned long rlim_max;
};
限制CPU占用时间,process address space,core dump file size,可以拥有的最大进程数(进程可以限制自己拥有的最大子进程数),等等。
五 PROCESS SWITCH
Linux中,hardware context一部分存在task_struct一部分存在kernel mode stack(不用TSS?)
2.6中,LINUX用软件的方法来实现process switch,而以前的版本中,用的是硬件far jmp。
两个优点。P.103(自己觉得还有个优点就是能够使LINUX更好移植?)
Process switch只在kernel mode 中发生。User mode 中使用的register已经存到kernel mode stack中。包括ss和esp。
80X86 includes tss(task stack segment) ,尽管LINUX中不用TSS,但是还是要SET UP tss,有两个原因。P104。
TSSD ,TSS descriptor,TSS描述符,tr register存放TSSD selector,GDT存放TSSD。具体参看CHAPTER 2
LINUX不用TSS,而将大部分硬件信息存在thread_struct中,eax,ebx,etc,存在kernel mode stack中。
六 执行进程切换
Ps occur at schedule() function
每次进程切换需要两步:1切换page global directory to install a new address space.
2 switching the kerel mode stack ande the hardware context.
Switch_to macro,has three para,prev,next,last. What dose the ‘last’ para do?see p106
七 创建进程
传统的UNIX系统都这样来创建进程:所有的父进程的资源被子进程复制。这样会相当的慢和低效,以为子进程很少修改和读所有的继承来的资源。
现代UNIX KERNEL这样来解决: p115
1. copy on write技术,
2. lightweight processes,允许父子共享PAGING TABLES
3. vfork()system call ,这时parent blocked ,until child exits or excute a new process.so parent process can’t modify data that needed by child process.
clone(),fork(),vfork() system calls的作用
1.clone()用来创建lightweight processes,这时在父进程的ADDRESS SPACE里面分出子进程的STACk,注意clone()里面的参数。
2.fork()的作用:相当于将CLONE()里面的FLAGS设置成SIGCHILD,其他clear。并且子进程的stack指向父进程的stack。
3.vfork()’functiong is as mentioned above.
auxiliary
adj.
辅助的, 补助的
do_fork() function, handles 3 functions above. 她的具体功能参见p117
例如 allocates PID for child process, invoke copy_process()
Copy_process() function,sets up the process descriptor,and other kernel data structure required for child process. about 28 operations in this function.
bestow
[bi5stEu]
vt.
给予, 安放
八 内核线程 kernel threads
encumber
v.
阻碍
内核线程用来做flushing disk caches,swapping out unused pages,servicing network connectiongs and so on.
Only use PAGE_OFFSET以后的地址,因为只占用内核空间。
用kernel_thread()来建立new kernel thread.在此之间也会调用do_fork(),clone_vm参数,因为不用给新的kernel thread分配地址空间,因为不需要USER MODE
Process0: 调用start_kernel() 来初始化内核的所有数据结构,并且创建process 1(kernel_thread()),调用后,excutes cpu_idle() func .
Process 1(也叫init):init() 调用 execve() 来唤出init。这个进程alive直到关机。
九 销毁进程
销毁进程用exit()库函数:exit()有3中情况会被调用:1用户主动调用。2在main()函数结束时3当一个不可回复的异常在内核态出现时。
Process termination :exit_group(),_exit() system call
上面两个system call分别调用,do_group_exit()和do_exit() (最终都调用do_exit())
Do_exit()的作用基本上有:1在process descriptor中置相应位;2将process descriptor中关于paging,semaphores,filesystem,open file descriptors,namespces,I/O permission bitmap这些东西通过exit_mm()等函数分离开;3调用exit_notify()通知他的父进程和子进程,子进程会加入另一个进程组中或者加入init porcess。4调用schedule(),来选择新的进程运行。
十 进程移除
如果子进程终止了,父进程需要得到子进程的终止号,用来看子进程是否正常结束(wait())。根据这种思想,内核不允许在进程终止以后就直接丢弃进程描述符里面的数据。所以引入EXIT_ZOMBIE状态。
最后release_task()函数用来将进程描述符里面的数据分离。具体参见p129