Linux 内核分析
Linux 内核分析
实验二 进程的创建与可执行程序的加载
一、查看进程
ps和pstree命令:
1.1 ps [options] [--help]
ps 列出当前终端下的进程
ps -A 列出所有进程
ps -e 列出所有进程
ps -l 显示较多进程信息
ps -el 以显示较多信息的方式列出所有进程
1.2 pstree [options]
树状显示进程信息
二、终止进程:Ctrl+C、killall、kill、
2.1 Ctrl+C
(1)
(2) killall <进程名>
(3) kill [信号代码] <进程PID>
三、从库函数的角度看进程
linux中可以通过fork()函数和exec()函数来创建和修改进程。fork()通过拷贝当前进程创建一个子进程。exec()函数负责读取可执行文件并将它载入地址空间开始运行。
3.1 fork()
linux 通过clone()系统调用来实现fork()。fork()调用do_fork(),[完成了大部分的创建工作],do_fork()调用copy_process(),copy_process()完成如下工作:
*1.调用dup_task_struct()为新进程创建一个内核栈,thread_info结构和task_struct,这些值与当前进程的值相同。此时,子进程和父进程的PID是一样的。
*2.检查新创建的子进程,当前用户所拥有的进程数目没有超出给他分配的资源的限制。
*3.子进程着手使自己与其父进程区别开来。进程描述符内的许多成员都要被清0或设为初始值。进程描述符的成员值并不是继承而来的,而主要是统计信息。进程描述符中的大多数数据是共享的。
*4.然后,子进程的状态被设置为task_uninterruptible()以保证它不会投入运行。
*5.copy_process()调用copy_flags()来更新task_struct的flags成员。表明进程是否拥有超级用户权限的PF_SUPERIV()被清0。表明进程还没有调用exec()的函数PF_FORKNOEXEC标志被设置。
*6调用get_pid()为进程获得一个有效的PID
*7根据传递给clone()的参数标志,copy_process()拷贝或共享打开的文件、文件系统信息、信号处理函数、进程地址空间和命名空间等。
*8让父进程和子进程平分剩余的时间片。
*9最后copy_process()做扫尾工作并返回一个指向子进程的指针
3.2 vfork()
vfork()系统调用和fork()一样,除了不复制父进程的也表项。子进程作为一个单独的进程在它父进程的地址空间中运行,父进程被阻塞直到子进程退出或执行exec().子进程不能对地址空间写入。
vfork()系统调用是通过向clone()系统调用传递一个特殊的标志位来进行的。
*1.在调用copy_process()时,task_struct的vfork_done被设置为null.
*2.在执行do_fork()时,如果给定特别标志,则vfork_done会指向一个特殊地址。
*3.子进程开始执行后父进程不会马上恢复执行,而是一直等待,直到vfork_done向父进程发出信号。
*4.在调用mm_release()时,该函数用于进程退出内存地址空间,并且检查vfork是否为空。如果不为空指向父进程。
*5.回到do_fork(),父进程醒来并返回。