进程管理

  进程和文件是Linux操作系统的两个最基本的抽象。

  进程是处于执行期的程序,进程不仅仅局限于一段可执行程序代码,通常还包含其他资源,如打开的文件、挂起的信号、内核内部数据、处理器状态、进程地址空间及一个或者多个执行线程(thread of execution)、当然还包括用来存放全局变量的数据段等。

  线程(thread)是内核调度的对象,每个线程都拥有一个独立的程序计数器(PC指针)、函数调用栈和一组寄存器值。在Linux内核中,线程只不过是一种特殊的进程,线程仅仅被视为一个与其他进程共享某些资源的进程。而不管是线程还是进程,在Linux内核看来,都是一个任务(task),由一个task_struct结构体描述,即任务描述符,任务描述符通常位于进程内核栈的栈底,32位系统中其大小为1.7KB左右。

  进程是资源管理的最小单位,线程是程序执行的最小单位。

  进程提供了两种虚拟机制:虚拟处理器和虚拟内存。他们给进程一种假象,独占CPU且独享内存。

1.1 task_struct

  Linux内核把进程存放在叫做任务队列(task list)的双向循环链表中,链表中的每一项都是task_struct结构体变量,描述一个具体进程的所有信息。

  Linux通过slab分配器分配task_struct结构,这样能达到对象复用和缓存着色(cache coloring)的目的。其机制是Linux内核预先分配一组大小都为task_struct结构体大小的内存(结构体数组),当创建一个进程时,快速分配一个task_struct结构体项(数组成员)。

  在2.6以前的内核中,各个进程的task_struct存放在他们内核栈的尾端。

  Linux内核通过PID来唯一标识每个进程,PID的最大值默认为32768,即一个short int短整型数据。可以通过设置/proc/sys/kernel/pid_max提高上限。

  在Linux内核中,访问任务通常需要获得指向其task_struct结构体的指针,通过current宏可以实现。

1.2 进程状态

  task_struct->state记录进程状态:

  TASK_RUNNING(运行状态)——正在执行,或者在运行队列中等待执行

  TASK_INTERRUPTIBLE(可中断状态)——进程正在睡眠(或者阻塞),等待某些条件达成之后,内核就会把进程状态设置为运行

  TASK_UNINTERUPTIBLE(不可中断状态)——与可中断状态相比,不可中断状态对信号不作响应

  TASK_ZOMBIE(僵死状态)——该进程已经结束,但是其父进程还没有调用wait4()系统调用,即为了让父进程能够获知它的消息,子进程的task_struct仍然被保留着

  TASK_STOPPED(停止状态)——进程停止执行,通常发生在进程接收到SIGSTOP/SIGTSTP/SIGTTIN/SIGTTOU等信号时

  Linux系统中,用户态所有进程都是PID为1的init进程的后代,内核在系统启动的最后阶段启动init进程。

  Linux中每个进程都必须有一个父进程,每个进程可以拥有0~N个子进程。如果父进程在子进程之前退出,必须有机制来保证子进程可以找到继父,否则这些成为孤儿的进程就会在退出时永远处于僵死状态(保留task_struct结构体而空耗资源),白白浪费内存。解决的方法是给子进程在当前线程组找一个线程作为继父,如果不行,就让init进程做它们的继父。

1.3 内核线程(kernel thread)

  内核经常需要在后台执行一些操作,这种任务可以通过内核线程完成——独立运行在内核空间的标准进程。内核线程和普通进程的区别在于内核线程没有独立的地址空间(实际上它的mm指针被设置为NULL)。它只在内核空间运行,从来不切换到用户空间。内核线程和普通进程一样,可以被调度,也可以被抢占。

进程调度

  Linux内核为多任务可抢占式内核。进程调度就是负责CPU资源的分配,满足所有进程对CPU资源的需求。

  调度程序中最基本的数据结构是可执行队列(run queue),现代CPU一般都是多核架构,Linux内核为每一个核维护一个唯一的可执行队列。

Linux高级调试与优化——进程管理和调度的更多相关文章

  1. Linux高级调试与优化——内存管理

    1.物理地址和虚拟地址 Linux采用页表机制管理内存,32位系统中页大小一般为4KB,物理内存被划分为连续的页,每一个页都有一个唯一的页号. 为了程序的的可移植性,进程往往需要运行在flat mem ...

  2. Linux高级调试与优化——gdb调试命令

    番外 2019年7月26日至27日,公司邀请<软件调试>和<格蠹汇编——软件调试案例集锦>两本书的作者张银奎老师进行<Linux高级调试与优化>培训,有幸聆听张老师 ...

  3. [Wolfgang Mauerer] 深入linux 内核架构 第二章 进程管理与调度【未完】

     作为Linux开发爱好者,从事linux 开发有三年多时间.做过bsp移植,熟悉u-boot代码执行流程:看过几遍<linux 设备驱动程序开发>,分析过kernel启动流程,写过驱动, ...

  4. Linux内核入门到放弃-进程管理和调度-《深入Linux内核架构》笔记

    进程优先级 硬实时进程 软实时进程 普通进程 O(1)调度.完全公平调度器 抢占式多任务处理(preemptive multitasking):各个进程都分配到一定的时间段可以执行.时间段到期后,内核 ...

  5. Linux高级调试与优化——用户态堆

    内存问题是软件世界的住房问题 嵌入式Linux系统中,物理内存资源通常比较紧张,而不同的进程可能不停地分配和释放不同大小的内存,因此需要一套高效的内存管理机制. 内存管理可以分为三个层次,自底向上分别 ...

  6. Linux高级调试与优化——信号量机制与应用程序崩溃

    背景介绍 Linux分为内核态和用户态,用户态通过系统调用(syscall)进入内核态执行. 用户空间的glibc库将Linux内核系统调用封装成GNU C Library库文件(兼容ANSI &am ...

  7. Linux高级调试与优化——ptrace

    ptrace (process trace) #include <sys/ptrace.h> long ptrace(enum __ptrace_request request, pid_ ...

  8. Linux高级调试与优化——同时抓取coredump和maps文件

    Linux内核源码 Documentation/sysctl/kernel.txt core_pattern: core_pattern: core_pattern is used to specif ...

  9. Linux高级调试与优化——内存泄漏实战分析

    最近在整理Linux调试方面的文档,正好碰到了一个内存泄漏踩栈的问题,借此机会记录一下分析过程. 首先,发现问题之后,赶紧看一下产生coredump文件没有,果不其然,产生了coredump,果断上g ...

随机推荐

  1. Python标准库、第三方库和外部工具汇总

    导读:Python数据工具箱涵盖从数据源到数据可视化的完整流程中涉及到的常用库.函数和外部工具.其中既有Python内置函数和标准库,又有第三方库和工具. 这些库可用于文件读写.网络抓取和解析.数据连 ...

  2. 主流浏览器内核(IE、Chrome、Firefox、Safari、Opera)

    IE浏览器,使用Trident浏览器内核,又称为IE内核.只用于Windows平台,而且并不是开源的: chrome浏览器,目前使用的是Blink浏览器内核.浏览器内核的演进过程:Chromium  ...

  3. avascript中实现垃圾桶的功能

    javascript中实现垃圾桶的功能,就像折垃圾桶在拖动目标上触发事件 (源元素):ondragstart - 用户开始拖动元素时触发ondrag - 元素正在拖动时触发ondragend - 用户 ...

  4. Linux下svn服务器的安装与配置-备份-恢复-计划任务

    简介:SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS.互联网上很多版本控制服务已从CVS迁移到Subvers ...

  5. linux库(程序)与包名联系

    一般地,dev为相关开发库包. curses--cursor optimization光标优化--libncurses5-dev 现在常用的是new curses(ncurses). 在ubuntu中 ...

  6. Redis位操作介绍

    在学习redis的过程了,看到了redis还能用于大数据处理,具体场景如下:腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,你能怎么做?千万别说给每个用户建立一个key,然后挨个记(你可以算一下需 ...

  7. Python基础:深浅拷贝

    对于数字.字符串深浅拷贝: import copy num = 0 copy_num = copy.copy(num) print("These are normal copy") ...

  8. excel匹配相应条件 自动填充数据

    =VLOOKUP(A6&B6,IF({1,0},Sheet3!$A$3:$A$505&Sheet3!$B$3:$C$505,Sheet3!$Q$3:$Q$505),2,0) =VLOO ...

  9. sizeof运算符、虚函数、虚继承考点(待修改)

    参考: http://blog.csdn.net/wangyangkobe/article/details/5951248 下面的文章解释有错误,不要看.......... 记住几句话: 编译器为每个 ...

  10. Python 操作 MySQL 数据库Ⅲ

    数据库查询操作 Python查询Mysql使用 fetchone() 方法获取单条数据, 使用fetchall() 方法获取多条数据. fetchone(): 该方法获取下一个查询结果集.结果集是一个 ...