linux内核设计与实现[第3章 摘抄]

第3章 进程管理

1 进程(process):处于执行期的程序和相关资源的总称
相关资源:
– 打开的文件
– 挂起的信号
– 内核内部数据
– 处理器状态
– 一个或多个具有内存映射的内存地址空间
– 一格或者多个执行线程
– 存放全局变量的数据段

2 线程(thread):在进程中活动的对象,拥有独立的:
– 程序计数器
– 进程栈
– 一组进程寄存器

3 内核调度的对象是thread而不是process

4 在现代操作系统中,进程提供两种虚拟机制:
– 虚拟处理器
– 虚拟内存

5 同一个进程中的线程可以共享虚拟内存,但拥有各自的虚拟处理器

6 fork()系统调用从内核返回两次:
– 一次回到父进程
– 一次回到新产生的子进程

7 进程的另一个名字是task

8 内核把进程的列表存放在叫做任务列表(task list)的双向循环链表中,链表中的每一项都是类型为task_struct、称为进程描述符(process description)的结构

/* task_struct定义 */
<linux/sched.h>

9 linux通过 slab分配器 分配 task_struct 结构

10 在x86上, struct thread_info定义如下:

扫描二维码关注公众号,回复: 1632806 查看本文章
<asm/thread_info.h>
struct thread_info {
    struct task_struct *task;
    __u32  flags;
    __u32  status;
    __u32  cpu;
    mm_segment_t addr_limit;
    unsigned int seg_on_uaccess_error:1;
    unsigned int uaccess:1;
};

11 内核通过一个唯一的进程标识值PID(proccess identification value)来标识每一个进程

12 系统中允许存在的进程的最大数目(受“linux/threads.h”中所定义PID的最大值的限制),可以通过更改 /proc/sys/kernel/pid_max来实现

13 进程描述符中的state域描述了进程的当前状态

14 设置当前进程状态

#include <linux/sched.h>
set_task_state(task, state);

15 进程上下文:当一个程序执行了系统调用后者触发某个异常,它就陷入了内核空间。此时,我们称内核“代表进程执行”并处于进程上下文中

16 内核在系统启动的最后阶段启动init进程。该进程读取系统的初始化脚本(initscript)并执行其他的相关程序,最终完成系统启动的整个过程

17 进程间的关系被放在进程描述符中

18 对于当前进程,可以通过如下方式获取父进程的进程描述符:

struct task_struct *my_parent = current->parent;

19 依次访问子进程:

struct task_struct *task;
struct list_head *list;

list_for_each(list, &current->children)
{
    /* task现在指向当前的某个子进程 */
    task = list_entry(list, struct task_struct, sibling);
}

20 对于给定的进程,获取链表中的前/下一个进程:

list_entry (task->tasks.prev, struct task_struct, tasks)

list_entry (task->tasks.next, struct task_struct, tasks)

21 进程创建
①fork()通过拷贝当前进程创建一个子进程
②exec()读取可执行文件并将其载入地址空间开始执行

22 任务队列是一个双向的循环链表

23 copy-on-write是一种可以推迟甚至免除拷贝数据的技术。资源复制只有在需要写入的时候才进行,在此之前,只是以只读方式共享

24 fork()的实际开销:
①复制父进程的页表
②给子进程创建唯一的进程描述符

17 linux通过clone()系统调用实现fork()
– fork->clone->do_fork->copy_proccess:
– ->dup_task_struct
– ->copy_flags
– ->alloc_pid

18 在现有内核线程中创建新的内核线程

struct task_struct *kthread_create (int (*threadfn)(void *data),
                    void *data,
                    const char namefmf[],
                    ...)

猜你喜欢

转载自blog.csdn.net/skyleemon/article/details/78640919