zoukankan      html  css  js  c++  java
  • Linux 源码阅读 进程管理

    Linux 源码阅读 进程管理

    版本:2.6.24

    1.准备知识

    1.1 Linux系统中,进程是最小的调度单位;

    1.2 PCB数据结构:task_struct (Location:linux-2.6.24includelinuxsched.h)(任务可以和进程混用)

    task_struct结构体

    2.设计思路图

    3.数据结构

    4.主要函数

    4.1创建进程

     1 long do_fork(unsigned long clone_flags,
     2           unsigned long stack_start,
     3           struct pt_regs *regs,
     4           unsigned long stack_size,
     5           int __user *parent_tidptr,
     6           int __user *child_tidptr)
     7 {
     8     struct task_struct *p;
     9     int trace = 0;
    10     long nr;
    11 
    12     if (unlikely(current->ptrace)) {
    13         trace = fork_traceflag (clone_flags);
    14         if (trace)
    15             clone_flags |= CLONE_PTRACE;
    16     }
    17 
    18     p = copy_process(clone_flags, stack_start, regs, stack_size,
    19             child_tidptr, NULL);
    20     /*
    21      * Do this prior waking up the new thread - the thread pointer
    22      * might get invalid after that point, if the thread exits quickly.
    23      */
    24     if (!IS_ERR(p)) {
    25         struct completion vfork;
    26 
    27         /*
    28          * this is enough to call pid_nr_ns here, but this if
    29          * improves optimisation of regular fork()
    30          */
    31         nr = (clone_flags & CLONE_NEWPID) ?
    32             task_pid_nr_ns(p, current->nsproxy->pid_ns) :
    33                 task_pid_vnr(p);
    34 
    35         if (clone_flags & CLONE_PARENT_SETTID)
    36             put_user(nr, parent_tidptr);
    37 
    38         if (clone_flags & CLONE_VFORK) {
    39             p->vfork_done = &vfork;
    40             init_completion(&vfork);
    41         }
    42 
    43         if ((p->ptrace & PT_PTRACED) || (clone_flags & CLONE_STOPPED)) {
    44             /*
    45              * We'll start up with an immediate SIGSTOP.
    46              */
    47             sigaddset(&p->pending.signal, SIGSTOP);
    48             set_tsk_thread_flag(p, TIF_SIGPENDING);
    49         }
    50 
    51         if (!(clone_flags & CLONE_STOPPED))
    52             wake_up_new_task(p, clone_flags);
    53         else
    54             p->state = TASK_STOPPED;
    55 
    56         if (unlikely (trace)) {
    57             current->ptrace_message = nr;
    58             ptrace_notify ((trace << 8) | SIGTRAP);
    59         }
    60 
    61         if (clone_flags & CLONE_VFORK) {
    62             freezer_do_not_count();
    63             wait_for_completion(&vfork);
    64             freezer_count();
    65             if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE)) {
    66                 current->ptrace_message = nr;
    67                 ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
    68             }
    69         }
    70     } else {
    71         nr = PTR_ERR(p);
    72     }
    73     return nr;
    74 }
    do_fork()函数(Locatiion:linux-2.6.24kernelfork.c)
    1 asmlinkage int sys_vfork(struct pt_regs regs)
    2 {
    3     return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
    4 }
    vfork()函数(location:linux-2.6.24archx86kernelprocess_32.c)
    1 asmlinkage int sys_fork(struct pt_regs regs)
    2 {
    3     return do_fork(SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
    4 }
    fork()函数(location:linux-2.6.24archx86kernelprocess_32.c)
    asmlinkage int sys_clone(struct pt_regs regs)
    {
        unsigned long clone_flags;
        unsigned long newsp;
        int __user *parent_tidptr, *child_tidptr;
    
        clone_flags = regs.ebx;
        newsp = regs.ecx;
        parent_tidptr = (int __user *)regs.edx;
        child_tidptr = (int __user *)regs.edi;
        if (!newsp)
            newsp = regs.esp;
        return do_fork(clone_flags, newsp, &regs, 0, parent_tidptr, child_tidptr);
    }
    clone()函数(location:linux-2.6.24archx86kernelprocess_32.c)

     

     1 /*
     2  * schedule() is the main scheduler function.
     3  */
     4 asmlinkage void __sched schedule(void)
     5 {
     6     struct task_struct *prev, *next;
     7     long *switch_count;
     8     struct rq *rq;
     9     int cpu;
    10 
    11 need_resched:
    12     preempt_disable();
    13     cpu = smp_processor_id();
    14     rq = cpu_rq(cpu);
    15     rcu_qsctr_inc(cpu);
    16     prev = rq->curr;
    17     switch_count = &prev->nivcsw;
    18 
    19     release_kernel_lock(prev);
    20 need_resched_nonpreemptible:
    21 
    22     schedule_debug(prev);
    23 
    24     /*
    25      * Do the rq-clock update outside the rq lock:
    26      */
    27     local_irq_disable();
    28     __update_rq_clock(rq);
    29     spin_lock(&rq->lock);
    30     clear_tsk_need_resched(prev);
    31 
    32     if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
    33         if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
    34                 unlikely(signal_pending(prev)))) {
    35             prev->state = TASK_RUNNING;
    36         } else {
    37             deactivate_task(rq, prev, 1);
    38         }
    39         switch_count = &prev->nvcsw;
    40     }
    41 
    42     if (unlikely(!rq->nr_running))
    43         idle_balance(cpu, rq);
    44 
    45     prev->sched_class->put_prev_task(rq, prev);
    46     next = pick_next_task(rq, prev);
    47 
    48     sched_info_switch(prev, next);
    49 
    50     if (likely(prev != next)) {
    51         rq->nr_switches++;
    52         rq->curr = next;
    53         ++*switch_count;
    54 
    55         context_switch(rq, prev, next); /* unlocks the rq */
    56     } else
    57         spin_unlock_irq(&rq->lock);
    58 
    59     if (unlikely(reacquire_kernel_lock(current) < 0)) {
    60         cpu = smp_processor_id();
    61         rq = cpu_rq(cpu);
    62         goto need_resched_nonpreemptible;
    63     }
    64     preempt_enable_no_resched();
    65     if (unlikely(test_thread_flag(TIF_NEED_RESCHED)))
    66         goto need_resched;
    67 }
    schdule()函数(Location:linux-2.6.24kernelsched.c

     4.2进程调度

  • 相关阅读:
    ORA00600 [3756]内部错误一例
    使用ALTER SYSTEM运行OS命令
    Oracle 审计参数AUDIT_SYSLOG_LEVEL介绍
    其他:ADO.NET访问Oracle数据库存储过程的本质
    其他:数据库访问模型
    VB6:通过OO4O访问Oracle存储过程返回的结果集
    Oracle学习笔记:编译PL/SQL对象
    Sqlserver:不可忽视的@@servername
    26个导航设计非常独特的网站案例欣赏
    非常棒的Web标准学习资源推荐
  • 原文地址:https://www.cnblogs.com/yocichen/p/10053219.html
Copyright © 2011-2022 走看看