Linux 第六周实验

姬梦馨

原创博客

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

一.进程控制块PCB——task_struct

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

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

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

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

  

4.函数的分析与理解

        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
	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

  

        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 */

  

 

/* 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

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

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

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

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 @ 2016-03-30 19:51  偷影子的人  阅读(311)  评论(0编辑  收藏  举报