深入理解linux内核读书笔记(第三章)
2015-06-17 16:14
435 查看
1. 进程是程序执行时的一个实例。
2. 从内核的角度看,进程是系统进行资源分配的实体。
3. linux 通过轻量级进程来支持多线程应用,每一个轻量级进程对应一个线程。
线程之间共享地址空间,打开的文件等资源,内核对每一个轻量级进程进行单独调度。
4. 一个线程组包含了一组线程用来实现多线程应用,对于getpid,kill, _exit等系统调用,线程组作为一个整体。
5. 内核通过task_struct 结构体来保存进程的信息。
6. 进程的状态 task_struct->state
(1) TASK_RUNNING, 正在cpu上执行或者等待被执行。
(2) TASK_INTERRUPTTBLE,进程正在被挂起直到满足一定条件后被唤醒。唤醒条件包括中断,发送信号,或者等待的条件得到满足。
(3) TASK_UNINTERRUPTTBLE, 和(2)类似,但是不能被信号唤醒。
(4) TASK_STOPPED, 进程执行暂停。
(5) TASK_TRACED, 进程被调试器暂停
7. 进程的退出状态 task_struct->exit_state
(1) EXIT_ZOMBIE, 进程执行已经结束,但是父进程还没有调用wait4或者waitpid之类的系统调用来获取该进程的信息。
(2)EXIT_DEAD, 进程的最后状态,进程正在被系统移除,将进程退出状态从EXIT_ZOMBIE改为EXIT_DEAD可以防止其他的进程对该进程调用wait系列的函数。
8. 内核提供了set_task_state 和set_current_state宏来对进程的状态进行赋值,并且保证赋值的操作被正确执行(不会与其他操作乱序)。
9. 每个可以被单独调度的执行实体都有task_struct 结构体,大部分对进程的引用都是通过task_struct 的指针来完成。
10. 线程组共有的id是第一个线程的pid,保存在tgid中,getpid返回tgid而不是pid。
11. 进程的thread_info 和 内核栈共同占有两个页面,也可以配置占有一个页面,其中,thread_info位于低地址处,内核栈底位于地址顶端。
12. 两个list增加的操作:
(1) list_add(n, p), 将n节点添加到p节点之后。
(2) list_add_tail(n, p), 将n节点添加到p节点之前。
13. 当只有一个孩子进程时,children.prev 和 children.next都指向那个孩子进程; 第一个孩子的sibling.prev指向parent,最后一个孩子的sibling.next也指向parent。
14. 进程状态为TASK_STOPPED, TASK_ZOMBIE和TASK_DEAD的进程没有用链表连接,因为这些进程只能通过pid或者特定的父进程来访问;
进程状态为TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE的进程根据等待事件细分为好多种,因此引入了等待队列。
15. __wait_queue结构体中,flags为1的话,表示是独占进程,内核有选择地唤醒进程; 为0的话是非独占进程,内核无条件唤醒。
16. 所有非独占进程位于等待队列的前面,而独占进程位于等待队列的后面,每次特定条件满足后,唤醒所有的非独占进程和一个独占进程。
17. 每个进程的资源配额保存在signal_struct 的rlim数组中,包括当前的使用量和最大使用量。子进程继承父进程的配额。
18. 在进程恢复执行之前必须要载入cpu寄存器的数据被称为硬件上下文,他是进程上下文的一个子集。
19. linux中,一部分硬件上下文保存在task_struct中,剩下的保存在内核栈中。
20. linux 2.6使用软件来进行进程切换,和x86提供的硬件切换相比,速度差不多,但是有更多的优化空间。
21. 进程切换发生在内核空间。当发生切换时,用户态的寄存器内容已经被保存在内核栈中,包括esp,和ss。
22. 尽管linux不使用硬件来切换进程,但是还是要求为每个cpu设置一个TSS段来保存硬件上下文。
23. 当进程从用户态切换到内核态时,从TSS中取得内核栈的地址。另外,当用户进程访问IO端口时,需要去检查TSS中的IO位图。通过tr寄存器来访问tss。
24. task_struct 中的thread_struct 保存了除通用寄存器的大部分寄存器,通用寄存器保存在内核栈中。
25. 每个进程切换包含两步:
(1)切换pgd,装入新的进程地址空间。
(2) 切换内核栈和硬件上下文。
26. 进程切换的第2步主要是由switch_to 宏来完成。switch_to的第三个last参数是一个输出参数,用来指向切换前的进程描述符。
27. thread_struct 中的esp0用来指向内核栈底(内核栈空), esp指向进程切换时的内核栈地址。(详见copy_thread)
28. linux 中,传统的fork 系统调用是通过 clone来实现的,flags(低字节)只包含SIGCHLD。
29. vfork中,包含的flags有SIGCHLD,CLONE_VM和CLONE_VFORK,child_stack和父进程相同。
30. clone, fork 和 vfork系统调用都是经过do_fork来处理。
31. 内核线程只运行在内核态,只使用大于PAGE_OFFSET的地址空间。
32. kernel_thread用来新建一个内核线程, 相当于调用do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL)。
33. 0进程(又叫idle进程, swapper进程), 是在内核初始化过程中创建的内核线程。进程描述符保存在init_task中。
34. start_kernel函数会创建另外一个内核线程,1进程,又叫init进程。该内核线程会调用init_post去执行用户的init进程。
35. release_task用来释放zombie进程的最后一个数据结构。
2. 从内核的角度看,进程是系统进行资源分配的实体。
3. linux 通过轻量级进程来支持多线程应用,每一个轻量级进程对应一个线程。
线程之间共享地址空间,打开的文件等资源,内核对每一个轻量级进程进行单独调度。
4. 一个线程组包含了一组线程用来实现多线程应用,对于getpid,kill, _exit等系统调用,线程组作为一个整体。
5. 内核通过task_struct 结构体来保存进程的信息。
6. 进程的状态 task_struct->state
(1) TASK_RUNNING, 正在cpu上执行或者等待被执行。
(2) TASK_INTERRUPTTBLE,进程正在被挂起直到满足一定条件后被唤醒。唤醒条件包括中断,发送信号,或者等待的条件得到满足。
(3) TASK_UNINTERRUPTTBLE, 和(2)类似,但是不能被信号唤醒。
(4) TASK_STOPPED, 进程执行暂停。
(5) TASK_TRACED, 进程被调试器暂停
7. 进程的退出状态 task_struct->exit_state
(1) EXIT_ZOMBIE, 进程执行已经结束,但是父进程还没有调用wait4或者waitpid之类的系统调用来获取该进程的信息。
(2)EXIT_DEAD, 进程的最后状态,进程正在被系统移除,将进程退出状态从EXIT_ZOMBIE改为EXIT_DEAD可以防止其他的进程对该进程调用wait系列的函数。
8. 内核提供了set_task_state 和set_current_state宏来对进程的状态进行赋值,并且保证赋值的操作被正确执行(不会与其他操作乱序)。
9. 每个可以被单独调度的执行实体都有task_struct 结构体,大部分对进程的引用都是通过task_struct 的指针来完成。
10. 线程组共有的id是第一个线程的pid,保存在tgid中,getpid返回tgid而不是pid。
11. 进程的thread_info 和 内核栈共同占有两个页面,也可以配置占有一个页面,其中,thread_info位于低地址处,内核栈底位于地址顶端。
12. 两个list增加的操作:
(1) list_add(n, p), 将n节点添加到p节点之后。
(2) list_add_tail(n, p), 将n节点添加到p节点之前。
13. 当只有一个孩子进程时,children.prev 和 children.next都指向那个孩子进程; 第一个孩子的sibling.prev指向parent,最后一个孩子的sibling.next也指向parent。
14. 进程状态为TASK_STOPPED, TASK_ZOMBIE和TASK_DEAD的进程没有用链表连接,因为这些进程只能通过pid或者特定的父进程来访问;
进程状态为TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE的进程根据等待事件细分为好多种,因此引入了等待队列。
15. __wait_queue结构体中,flags为1的话,表示是独占进程,内核有选择地唤醒进程; 为0的话是非独占进程,内核无条件唤醒。
16. 所有非独占进程位于等待队列的前面,而独占进程位于等待队列的后面,每次特定条件满足后,唤醒所有的非独占进程和一个独占进程。
17. 每个进程的资源配额保存在signal_struct 的rlim数组中,包括当前的使用量和最大使用量。子进程继承父进程的配额。
18. 在进程恢复执行之前必须要载入cpu寄存器的数据被称为硬件上下文,他是进程上下文的一个子集。
19. linux中,一部分硬件上下文保存在task_struct中,剩下的保存在内核栈中。
20. linux 2.6使用软件来进行进程切换,和x86提供的硬件切换相比,速度差不多,但是有更多的优化空间。
21. 进程切换发生在内核空间。当发生切换时,用户态的寄存器内容已经被保存在内核栈中,包括esp,和ss。
22. 尽管linux不使用硬件来切换进程,但是还是要求为每个cpu设置一个TSS段来保存硬件上下文。
23. 当进程从用户态切换到内核态时,从TSS中取得内核栈的地址。另外,当用户进程访问IO端口时,需要去检查TSS中的IO位图。通过tr寄存器来访问tss。
24. task_struct 中的thread_struct 保存了除通用寄存器的大部分寄存器,通用寄存器保存在内核栈中。
25. 每个进程切换包含两步:
(1)切换pgd,装入新的进程地址空间。
(2) 切换内核栈和硬件上下文。
26. 进程切换的第2步主要是由switch_to 宏来完成。switch_to的第三个last参数是一个输出参数,用来指向切换前的进程描述符。
27. thread_struct 中的esp0用来指向内核栈底(内核栈空), esp指向进程切换时的内核栈地址。(详见copy_thread)
28. linux 中,传统的fork 系统调用是通过 clone来实现的,flags(低字节)只包含SIGCHLD。
29. vfork中,包含的flags有SIGCHLD,CLONE_VM和CLONE_VFORK,child_stack和父进程相同。
30. clone, fork 和 vfork系统调用都是经过do_fork来处理。
31. 内核线程只运行在内核态,只使用大于PAGE_OFFSET的地址空间。
32. kernel_thread用来新建一个内核线程, 相当于调用do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL)。
33. 0进程(又叫idle进程, swapper进程), 是在内核初始化过程中创建的内核线程。进程描述符保存在init_task中。
34. start_kernel函数会创建另外一个内核线程,1进程,又叫init进程。该内核线程会调用init_post去执行用户的init进程。
35. release_task用来释放zombie进程的最后一个数据结构。
相关文章推荐
- linux 命令——46 vmstat(转)
- Linux中7个用来浏览网页和下载文件的命令
- linux 磁盘读写性能测试
- linux 关闭防火墙
- linux系统灵活运用灯[android课程3]
- linux 命令——45 free(转)
- Linux 用户的 3 个命令行小技巧(转载)
- 处理图片大小的linux命令
- Linux下时间范围判断的程序流程及其C代码实现
- 全球最受欢迎的十大Linux发行版(图)
- Linux 技巧:让进程在后台可靠运行的几种方法
- 装了Linux之后的事
- linux 命令——44 top (转)
- Centos上安装samba配置后,windows登陆root没有写权限
- linux下mysql的root密码忘记解决方
- linux 命令——43 killall(转)
- Linux下更改目录及其下的子目录和文件的访问权限
- linux下简单将python的django开发框架运行起来
- linux 命令——42 kill (转)
- [译] Linux 用户的 3 个命令行小技巧