`

Linux内核的进程管理

阅读更多

1,进程的概念

    进程就是处于执行期的程序,包括代码段,打开的文件,挂起的信号,内核内部数据,处理器状态,内存地址空间,一个或多个执行线程,数据段等。Linux内核对进程和线程并不做特殊的区分。

    内核把进程也叫做任务,进程描述符的数据结构类型为task_struct,在32位机器上有1.7KB。

    struct task_struct {
         volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
          struct thread_info *thread_info;
          unsigned long flags; /* per process flags, defined below */
          unsigned long ptrace;

          int prio, static_prio;
          struct list_head run_list;
          prio_array_t *array;

          struct mm_struct *mm, *active_mm;

         /* task state */
          struct linux_binfmt *binfmt;
          pid_t pid;
          pid_t tgid;
          struct task_struct *real_parent; /* real parent process (when being debugged) */
          struct task_struct *parent; /* parent process */
          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 */
          struct timespec start_time;
         /* process credentials */
          uid_t uid,euid,suid,fsuid;
          gid_t gid,egid,sgid,fsgid;
          struct user_struct *user;
          unsigned short used_math;
          char comm[16];
         /* CPU-specific state of this task */
          struct thread_struct thread;
         /* filesystem information */
          struct fs_struct *fs;
         /* open file information */
          struct files_struct *files;
         /* signal handlers */
          struct signal_struct *signal;
          struct sighand_struct *sighand;

          sigset_t blocked, real_blocked;
          struct sigpending pending;
          sigset_t *notifier_mask;

          struct backing_dev_info *backing_dev_info;

          struct io_context *io_context;
    };

    进程描述符的state描述当前进程的状态:

    TASK_RUNNING:正在执行,或在运行队列中

    TASK_INTERRUPTIBLE:可中断的睡眠,阻塞状态;等待某些条件的成立,或接收到信号提前被唤醒。

    TASK_UNINTERRUPTIBLE:不可中断的睡眠,不对信号做出响应。

    TASK_TRACED:被其他进程跟踪的进程

    TASK_STOPPED:停止,通常在接收到SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU等信号。

    TASK_ZOMBIE:僵死状态,进程执行结束,父进程还没有发布waitpid()系统调用

    TASK_DEAD:最终状态

 
   
 2,进程创建

    fork()通过写时拷贝当前进程创建一个子进程,写时拷贝是一种推迟甚至免除拷贝数据的技术,内核并不复制整个进程地址空间,而是让父进程与子进程共享同一个拷贝,只有在需要写入的时候,数据才会复制,从而使各个进程拥有各自的拷贝。fork()只复制父进程的页表以及给子进程创建唯一的进程描述符,子进程与父进程的区别仅仅在于PID和某些资源和统计量的不同。exec()函数负责读取可执行文件并将其载入地址空间。

从内核的角度说,它没有线程这个概念,Linux把所有的线程当作进程来实现,内核没有特别的算法或定义特别的数据结构来表示线程,线程仅仅视为一个与其他进程共享某些资源的进程,每个线程拥有自己的task_struct,所以在内核看来,它就是一个普通的进程。

    创建线程:

    clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, 0)

    创建进程:

     clone(SIGCHLD, 0)

3,CFS公平调度

    CFS的出发点基于一个简单的理念:进程调度的效果应如同系统具备一个理想中的完美多任务处理器,每一个进程将能获得1/N的处理器时间,N是指可运行进程的数量。在任何可测量的周期内,我们给予N个进程中每一个进程同样多的运行时间。

    CFS的做法是允许每一个进程运行一段时间,循环轮转,选择运行最少的进程作为下一个运行的进程,而不再采用分配给每一个进程时间片的做法了。CFS在所有可运行的进程总数基础上计算出一个进程应该运行多久,nice值在CFS中被作为进程获得的处理器运行比的权重。不是完善的公平,只是近乎完美,在多进程的环境下,降低了调度延迟带来的不公平性。

    CFS虚拟运行时间来记录一个程序运行了多长时间及它还应该运行多久,CFS调度算法的核心就是选择具有最小虚拟运行时间的进程,它使用红黑树来组成可运行进程队列。

4,调度器入口

    进程调度的主要入口点是函数schedule(),它是其他内核模块调用进程调度器的入口

5,进程睡眠

    进程睡眠有多种原因,无法读取IO更多的数据,无法获取信号量,互斥锁或某个硬件事件。进程把自己标记成休眠状态,从可执行进程的红黑树中移出,放入等待队列,然后调用schedule()函数选择和执行一个其他进程。唤醒的过程刚好相反,进程被置为可执行,从等待队列中移到调度器的红黑树中。休眠通过等待队列进行处理,等待队列是由等待某些事件发生的进程组成的简单链表,内核用wait_queue_head_t来表示等待队列:

    struct __wait_queue_head{

        spinlock_t lock;

        struct list_head task_list;

    };

    typedef struct __wait_queue_head_t wait_queue_head_t;

    等待队列链表的元素类型为wait_queue_t;

    struct __wait_queue{

        unsigned int flags;

        struct task_sruct *task;

        wait_queue_func_t func;

        struct list_head task_list;

    };

    typedef struct __wait_queue wait_queue_t;

 

    DEFINE_WAIT(wait);

    /*初始化一个wait_queue_t类型的变量,并用当前进程的描述符和唤醒函数

    autoremove_wake_function()的地址初始化。*/

    add_wait_queue(q, &wait); //将wait加入到等待队列q中

    while(!condition){

        prepare_to_wait(&q, &wait, TASK_INTERRUPTIBLE);

        if(signal_pending(current))

            /*处理信号*

        schedule();

    }

6,唤醒

    唤醒操作通过函数wake_up()进行,它会唤醒等待队列的所有进程,将进程设置为TASK_RUNNING状态,调用enqueue_task()将此进程放入到红黑树中。

    void wake_up(wait_queue_head_t *q)

    {

        struct list_head *tmp;

        wait_queue_t *curr;

        list_for_each(tmp, &q->task_list){

            curr = list_entry(tmp, wait_queue_t, task_list);

            if(curr->func(curr, TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE, 0, NULL) && curr->flags)

                break;

        }

    }

  • 大小: 96 KB
分享到:
评论

相关推荐

    linux内核进程管理

    纲要 1、linux进程管理的模块组织框架 2、相关数据结构。 3、进程调度原则,调度算法,。... 进程管理涉及的内核机制:bottom-half处理,等待队列 Linux/SMP的进程管理和调度技术 7、概述2.4的新特点

    Linux内核进程管理目录1

    Linux内核进程管理是操作系统的核心组成部分,它负责创建、调度、同步和销毁系统中的进程。在Linux中,进程是执行程序的实例,每个进程都有自己的内存空间和上下文。本文将深入探讨Linux内核4.9.76版本中关于进程...

    Linux内核进程管理之进程ID.pdf

    Linux内核进程管理是一个复杂的主题,涉及对进程的创建、调度和回收等一系列操作。其中,进程ID(PID)作为进程的唯一标识,起着至关重要的作用。在Linux操作系统中,每个进程都有一个唯一的PID,它用于区分系统中的...

    深入理解Linux内核 第七章进程管理

    ### 深入理解Linux内核之进程管理 #### 一、调度策略介绍 Linux操作系统以其高度可定制性和灵活性著称,在进程管理方面更是如此。本章节主要围绕Linux内核中的进程管理和调度策略进行深入探讨。 **传统的调度算法...

    linux内核简介,进程管理,进程调度等等

    这个压缩包包含了关于Linux内核的深入讲解,特别是关于进程管理和进程调度的内容。 首先,让我们从Linux内核的简介开始。Linux内核是由林纳斯·托瓦兹开发的开源操作系统内核,它遵循GNU General Public License,...

    Linux 内核结构与进程管理

    Linux内核是操作系统的核心部分,负责管理系统的硬件资源和提供软件服务...了解和掌握Linux内核结构与进程管理对于系统管理员和开发者来说至关重要,因为这有助于优化系统性能,解决系统问题,以及开发和调试应用程序。

    Linux内核进程切换

    Linux内核中进程切换ppt文档,主要介绍Linux内核中进程切换时进行了哪些操作。

    Linux内核进程调度与控制的实现.pdf

    Linux 内核进程调度与控制是整个 Linux 系统的核心部分,负责管理进程对 CPU 的访问。 Linux 进程调度的实现基于优先级的进程调度算法,选择最值得运行的进程。 Linux 内核的整体结构包括五个主要的子系统,进程调度...

    Linux内核进程隐藏技术在动态取证中的应用

    linux内核隐藏进程动态取证,实验效果很好

    Linux内核设计与实现(第三版中文高清带目录)_linux_linux内核_

    2. **进程管理**:Linux内核通过调度算法管理进程的执行,如抢占式调度、实时调度策略等。此外,还包括进程间的通信(IPC)机制,如管道、信号量、消息队列等。 3. **内存管理**:内核负责物理和虚拟内存的分配、...

    Linux进程管理器

    进程管理器程序,用来替代cron-tab和supervisor,实现了高精度计时器,可以用来监控启动各种长作业,短作业,其中提供各种进程启动的时间限制和控制接口

    Linux内核完全注释:基于0.11内核(V5.0)_0.11内核_linux_linux内核完全注释_Linux内核注释_

    2. 进程管理:内核如何创建、调度、终止进程,以及如何处理进程间的通信(IPC)如信号、管道、套接字等。这部分内容有助于理解多任务环境下操作系统的工作方式。 3. 内存管理:了解Linux如何分配和回收内存,包括...

    LINUX内核的进程调度策略.doc

    调度策略主要包括调度时机、调度方式和调度策略,这三个方面共同构成了Linux内核中复杂的进程管理机制。 首先,调度时机在Linux内核中分为两种类型:自愿调度和非自愿调度。自愿调度是指进程主动通过系统调用如`...

    深入理解Linux内核 + Linux内核设计与实现 英文版

    书中的内容涵盖了进程管理、内存管理、文件系统、设备驱动、网络协议栈等方面,通过实例解析,让读者能够明白各个模块如何协同工作,构建出高效稳定的系统环境。作者用浅显易懂的语言解释复杂的概念,适合初学者入门...

    Linux内核分析(进程与进程调度) 北航软件学院课件

    ### Linux内核分析:进程与进程调度 #### 知识点概述 北航软件学院的Linux内核分析课程深入探讨了Linux操作系统的核心机制之一:进程与进程调度。本课程不仅覆盖了理论知识,还提供了实践指导,通过分析关键源代码...

    Linux内核进程隐藏技术在动态取证中的应用.pdf

    "Linux内核进程隐藏技术在动态取证中的应用.pdf" 本文档讨论了Linux内核进程隐藏技术在动态取证中的应用。动态取证是指在系统正常运行的状态下,获取目标主机中的所有数据,以重构实际的犯罪事实。该技术可以用于...

    深度:一文看懂Linux内核!Linux内核架构和工作原理详解

    理解Linux内核最好预备的知识点:懂C语言懂一点操作系统的知识熟悉少量相关算法懂计算机体系结构Linux内核的特点:结合了unix操作系统的一些基础概念Linux内核的任务:1.从技术层面讲,内核是硬件与软

    Linux 2.6内核进程调度策略与算法分析.pdf

    "Linux 2.6内核进程调度策略与算法分析" Linux 2.6内核进程调度策略与算法分析是Linux操作系统中非常重要的一部分。Linux 2.6内核采用了新的调度器,该调度器基于O(1)算法,取消了全局同步和重算循环,每个CPU分配...

Global site tag (gtag.js) - Google Analytics