Linux 第六周实验

姬梦馨

原创博客

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

一.进程控制块PCB——task_struct

    1.操作系统的三大管理功能包括:进程管理、内存管理、 文件系统。

    2.PCB task_struct中包含:进程状态、进程打开的文件、进程优先级信息

    3: 进程的状态不同于操作系统

1
2
3
4
5
一个即在的进程调用fork创建一个新的进程。
进程被高优先级抢占。
do_exit 进程退出。
事件发生或资源可用,可被唤醒进入队列。
TASK_RUNNING具体是就绪还是执行,要看系统当前的资源分配情况

  

4.函数的分析与理解

1
2
3
4
5
6
7
8
9
10
11
12
13
    struct task_struct {          :运行状态 volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
void *stack;    :内核堆栈;进程运行堆栈.
atomic_t usage;
unsigned int flags; :进程标识符
unsigned int ptrace;
    #ifdef CONFIG_SMP         :条件编译,多处理器
struct llist_node wake_entry;
int on_cpu;
struct task_struct *last_wakee;
unsigned long wakee_flips;
unsigned long wakee_flip_decay_ts;
    int wake_cpu;
    #endif
1
2
3
4
5
6
7
8
9
struct list_head tasks;        双向进程链表
     #ifdef CONFIG_SMP
struct plist_node pushable_tasks;
struct rb_node pushable_dl_tasks;
    #endif
struct mm_struct *mm, *active_mm;  地址空间
    #ifdef CONFIG_COMPAT_BRK
unsigned brk_randomized:1;
   #endif

  

1
2
3
4
5
6
7
    struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports        
     /*    进程父子关系
 * children/sibling forms the list of my natural children
 */
struct list_head children;  /* list of my children */
struct list_head sibling;   /* linkage in my parent's children list */
struct task_struct *group_leader;   /* threadgroup leader */

  

 

1
2
3
4
5
6
7
8
9
10
11
/* CPU-specific state of this task */    CPU相关状态,进程切换
    struct thread_struct thread
/* filesystem information */             文件相关,打开描述列表
    struct fs_struct *fs;
/* open file information */
    struct files_struct *files;
/* namespaces */                         调用                   
    struct nsproxy *nsproxy;
/* signal handlers */                    信号处理
    struct signal_struct *signal;
    struct sighand_struct *sighand;

二:进程的创建

1. fork

1
2
fork系统调用在父进程和子进程各返回一次
子进程中返回的是0,父进程中返回值是子进程的pid。

2. 创建一个新进程在内核中的执行过程

fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建。
1
2
创建新进程是通过复制当前进程实现的。
do_fork主要是复制了父进程的task_struct,得到子进程.<br>   do_fork()要修改复制过来的进程数据,比如pid、进程链表等。
  • 调用copy_process,将当前进程复制一份出来给子进程,并且为子进程设置相应地上下文信息。
  • 调用wake_up_new_task,将子进程放入调度器的队列中,此时的子进程就可以被调度进程选中运行。

3. 子进程系统调用处理过程

   fork出来的子进程是从ret_from_fork开始执行的,然后跳转到syscall_exit,从系统调用中返回。

 

三:实践    使用gdb跟踪分析一个fork系统调用内核处理函数sys_clone

1. 启动MenuOS

2.gdb调试fork命令 : qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S

 

3.编译内核,可以看到fork命令

 

 

4.设置断点

 

5.  调试结果

 

停在了父进程

 

 

总结:

Linux通过复制父进程来创建一个新进程,通过调用do_ fork来实现并为每个新创建的进程动态地分配一个task_ struct结构。

子进程是从ret_ from_ fork开始执行的。

 

posted @   偷影子的人  阅读(312)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示