进程的描述与进程的创建

阅读理解task_struct数据结构,它包含了

进程状态、运行时间、调度信息、进程的通讯状况、task_struct型链表连接指针

、标号,决定改进程归属、可以读写打开的一些文件信息、进程上下文和内核上下文、处理器上下文、内存信息等

  1. struct task_struct { volatile long state; 状态信息
  2. unsigned long flags; //进程号,在调用fork()时给出
  3. int sigpending; //进程上是否有待处理的信号
  4. mm_segment_t addr_limit; //进程地址空间,区分内核进程与普通进程在内存存放的不同位置
  5. //0-0xBFFFFFFF for user-thead
  6. //0-0xFFFFFFFF for kernel-thread //调度标志,表示该进程是否需要重新调度,若非0,则当从内核态返回到用户态,会发生调度
  7. volatile long need_resched;
  8. int lock_depth; //锁深度
  9. long nice; //进程的基本时间片
  10. //进程的调度策略,有三种,实时进程:SCHED_FIFO,SCHED_RR, 分时进程:SCHED_OTHER unsigned long policy; 
  11. struct mm_struct *mm; //进程内存管理信息 
  12. int processor; //若进程不在任何CPU上运行, cpus_runnable 的值是0,否则是1 这个值在运行队列被锁时更新 
  13. unsigned long cpus_runnable, cpus_allowed; 
  14. struct list_head run_list; //指向运行队列的指针 
  15. unsigned long sleep_time; //进程的睡眠时间 
  16. //用于将系统中所有的进程连成一个双向循环链表, 其根是init_task 
  17. struct task_struct *next_task, *prev_task; 
  18. struct mm_struct *active_mm; 
  19. struct list_head local_pages; //指向本地页面 
  20. unsigned int allocation_order, nr_local_pages; struct linux_binfmt *binfmt; //进程所运行的可执行文件的格式 
  21. int exit_code, exit_signal; 
  22. int pdeath_signal; //父进程终止是向子进程发送的信号 
  23. unsigned long personality; 
  24. int did_exec:1; pid_t pid; //进程标识符,用来代表一个进程 
  25. pid_t pgrp; //进程组标识,表示进程所属的进程组 
  26. pid_t tty_old_pgrp; //进程控制终端所在的组标识 
  27. pid_t session; //进程的会话标识
  28. pid_t tgid; 
  29. int leader; //表示进程是否为会话主管 
  30. struct task_struct *p_opptr,*p_pptr,*p_cptr,*p_ysptr,*p_osptr; struct list_head thread_group; //线程链表 
  31. struct task_struct *pidhash_next; //用于将进程链入HASH表 
  32. struct task_struct **pidhash_pprev; 
  33. wait_queue_head_t wait_chldexit; //供wait4()使用 
  34. struct completion *vfork_done; //供vfork() 使用 
  35. unsigned long rt_priority; //实时优先级,用它计算实时进程调度时的weight值 …… 
  36. };
  37. 进程创建分析 
  38. fork函数到底如何进行对应的内核处理过程sys_clone。
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <unistd.h>
  42. int main(int argc, char * argv[])
  43. { int pid;    /* fork another process */
  44.     pid = fork();
        if (pid < 0)
        {
            /* error occurred */
            fprintf(stderr,"Fork Failed!");
            exit(-1);
        }
        else if (pid == 0)
        {
            /* child process */
            printf("This is Child Process!\n");
        }
        else
        {
            /* parent process  */
            printf("This is Parent Process!\n");
            /* parent will wait for the child to complete*/
            wait(NULL);
            printf("Child Complete!\n");
        }
    }
    
    
  45. ti = alloc_thread_info_node(tsk, node);
  46. tsk->stack = ti; 
  47. setup_thread_stack(tsk, orig); //这里只是复制thread_info,而非复制内核堆栈
  48. *childregs = *current_pt_regs(); //复制内核堆栈 
  49. childregs->ax = 0; //为什么子进程的fork返回0,这里就是原因! 
  50. p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶 
  51. p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址
  52. static struct task_struct *dup_task_struct(struct task_struct *orig)
  53. {
    1.   struct task_struct *tsk;
    2. struct thread_info *ti;
    3. int node = tsk_fork_get_node(orig);
    4. int err;
    5. tsk = alloc_task_struct_node(node);
    6. if (!tsk)
    7. return NULL;
    8. ti = alloc_thread_info_node(tsk, node);
    9. if (!ti)
    10.  goto free_tsk;
    11. err = arch_dup_task_struct(tsk, orig);
    12. if (err)
    13.  goto free_ti;
    14. tsk->stack = ti;
    15. # ifdef CONFIG_SECCOMP
    16. tsk->seccomp.filter = NULL;
    17. # endif
    18. setup_thread_stack(tsk, orig);
    19. clear_user_return_notifier(tsk);
    20. clear_tsk_need_resched(tsk);
    21. set_task_stack_end_magic(tsk);
    22. # ifdef CONFIG_CC_STACKPROTECTOR
    23. tsk->stack_canary = get_random_int();
    24. # endif
    25. atomic_set(&tsk->usage, 2);
    26. # ifdef CONFIG_BLK_DEV_IO_TRACE
    27. tsk->btrace_seq = 0;
    28. # endif
    29. tsk->splice_pipe = NULL;
    30. tsk->task_frag.page = NULL;
    31. account_kernel_stack(ti, 1);
    32. return tsk;
    33. free_ti:
    34. free_thread_info(ti);
    35. free_tsk:
    36. free_task_struct(tsk);
    37. return NULL;
    38. }
int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg, struct task_struct *p) { ... *childregs = *current_pt_regs(); childregs->ax = 0; if (sp) childregs->sp = sp; p->thread.ip = (unsigned long) ret_from_fork; ... }/*ret from_fork*/ENTRY(ret_from_fork)
    CFI_STARTPROC
    pushl_cfi %eax
    call schedule_tail
    GET_THREAD_INFO(%ebp)
    popl_cfi %eax
    pushl_cfi $0x0202       # Reset kernel eflags
    popfl_cfi
    jmp syscall_exit
    CFI_ENDPROC
END小结:(ret_from_fork)新进程是从在ret_from_fork之前,也就是在copy_thread()函数中*childregs = *current_pt_regs();该句将父进程的regs参数赋值到子进程的内核堆栈,,使子进程拥有了SAVE ALL中压入栈的参数,故在ret from_fork时可以返回当前子进程的信息。 

时间: 2024-10-13 12:38:49

进程的描述与进程的创建的相关文章

Linux内核分析——进程的描述和进程的创建

Linux内核分析——进程的描述和进程的创建 20135111李光豫 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.实验内容 阅读理解task_struct数据结构http://codelab.shiyanlou.com/xref/linux-3.18.6/include/linux/sched.h#1235: 分析fork函数对应的内核处理过程sys_clone,理解创建一个新进

作业6:进程的描述和进程的创建 20135115臧文君

进程的描述和进程的创建 注:作者:臧文君,原创作品转载请注明出处,<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.进程的描述 操作系统的三大功能:进程管理,内存管理和文件系统. 1.进程描述符task_struct数据结构 (1)进程控制块PCB---task_struct (2)进程描述符提供了内核所需了解的进程信息. task_struct中包含:进程状态,进程打开的文件,进程优先级信息. tty_st

第六节 进程的描述和进程的创建

第六周 进程的描述和进程的创建 By 20135217 孙小博 本周的主要内容: 如何描述一个进程:进程描述符的数据结构: 如何创建一个进程:内核是如何执行的,以及新创建的进程从哪里开始执行: 使用gdb跟踪新进程的创建过程. 进程的描述 操作系统三大功能: 进程管理(最核心最基础) 内存管理 文件系统 进程描述符task_struct数据结构 task _ struct:为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息.struct task_struct

进程的描述和进程的创建——第六周(20135304刘世鹏)

进程的描述和进程的创建  作者:刘世鹏20135304                                                                                       <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000  一.进程的描述 1.1进程描述符task_struck数据结构(一) (1)操作系统的三大功能:进程管理.内存管理.文件系统. (2)

LINUX内核分析第六周学习总结——进程的描述和进程的创建

LINUX内核分析第六周学习总结——进程的描述和进程的创建 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.知识概要 进程的描述 进程描述符task_struct数据结构(一) 进程描述符task_struct数据结构(二) 进程的创建 进程的创建概览及fork一个进程的用户态代码 理解进程创建过程复杂代码的方法 浏览进程创建过程相关的关键代码 创建的新进程是从哪里开始执行的

linux作业六——进程的描述和进程的创建

进程的描述和进程的创建 一.进程描述符task_struct 为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息. 代码关键点: 1.Struct list_head task进程链表,双向循环链表链接. 2.Struct mm_struct *mm,*active_mm进程地址空间,内存管理 3.每个进程都有自己独立的4G进程地址空间. 4.Struct thread Struct thread当前任务相关的CPU代码 5.Struct fs_Struct

《Linux内核分析》第六周笔记 进程的描述和进程的创建

进程的描述和进程的创建 一.进程的描述 1.进程描述符task_struct数据结构(一) 操作系统的三大功能:进程管理(核心).内存管理.文件系统. 进程控制块PCB——task_struct(进程描述符):为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息. struct task_struct数据结构很庞大,共有约400行代码 Linux进程的状态与操作系统原理中的描述的进程状态似乎有所不同,比如就绪状态和运行状态都是TASK_RUNNING,为什么呢?

20135239益西拉姆 Linux内核分析 进程的描述和进程的创建

[益西拉姆 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] 第六周 进程的描述和进程的创建 一. 进程的描述 进程控制块PCB——task_struct 为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息. struct task_struct数据结构很庞大 Linux进程的状态与操作系统原理中的描述的进程状态似乎有所不同,比如就绪状态和运行状态都是

20135327郭皓--Linux内核分析第六周 进程的描述和进程的创建

进程的描述和进程的创建 一.进程的描述 操作系统三大功能: 进程管理 内存管理 文件系统 进程描述符task_struct数据结构 task _ struct:为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息. 进程的状态:Linux进程的状态(就绪态.运行态.阻塞态) 进程的标示pid:用来标示进程 进程描述符task_struct数据结构(重要部分): 1 struct task_struct { 2 volatile long state; /* 进程

Linux内核分析之六——进程的描述与进程的创建

作者:姚开健 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 进程的描述 Linux系统的进程由一个进程描述符PCB,即task_struct结构体来描述,其在内核中代码实现如下: struct task_struct { 1236 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ 1237 void