Linux高级调试与优化——进程管理和调度
进程管理
进程和文件是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高级调试与优化——进程管理和调度的更多相关文章
- Linux高级调试与优化——内存管理
1.物理地址和虚拟地址 Linux采用页表机制管理内存,32位系统中页大小一般为4KB,物理内存被划分为连续的页,每一个页都有一个唯一的页号. 为了程序的的可移植性,进程往往需要运行在flat mem ...
- Linux高级调试与优化——gdb调试命令
番外 2019年7月26日至27日,公司邀请<软件调试>和<格蠹汇编——软件调试案例集锦>两本书的作者张银奎老师进行<Linux高级调试与优化>培训,有幸聆听张老师 ...
- [Wolfgang Mauerer] 深入linux 内核架构 第二章 进程管理与调度【未完】
作为Linux开发爱好者,从事linux 开发有三年多时间.做过bsp移植,熟悉u-boot代码执行流程:看过几遍<linux 设备驱动程序开发>,分析过kernel启动流程,写过驱动, ...
- Linux内核入门到放弃-进程管理和调度-《深入Linux内核架构》笔记
进程优先级 硬实时进程 软实时进程 普通进程 O(1)调度.完全公平调度器 抢占式多任务处理(preemptive multitasking):各个进程都分配到一定的时间段可以执行.时间段到期后,内核 ...
- Linux高级调试与优化——用户态堆
内存问题是软件世界的住房问题 嵌入式Linux系统中,物理内存资源通常比较紧张,而不同的进程可能不停地分配和释放不同大小的内存,因此需要一套高效的内存管理机制. 内存管理可以分为三个层次,自底向上分别 ...
- Linux高级调试与优化——信号量机制与应用程序崩溃
背景介绍 Linux分为内核态和用户态,用户态通过系统调用(syscall)进入内核态执行. 用户空间的glibc库将Linux内核系统调用封装成GNU C Library库文件(兼容ANSI &am ...
- Linux高级调试与优化——ptrace
ptrace (process trace) #include <sys/ptrace.h> long ptrace(enum __ptrace_request request, pid_ ...
- Linux高级调试与优化——同时抓取coredump和maps文件
Linux内核源码 Documentation/sysctl/kernel.txt core_pattern: core_pattern: core_pattern is used to specif ...
- Linux高级调试与优化——内存泄漏实战分析
最近在整理Linux调试方面的文档,正好碰到了一个内存泄漏踩栈的问题,借此机会记录一下分析过程. 首先,发现问题之后,赶紧看一下产生coredump文件没有,果不其然,产生了coredump,果断上g ...
随机推荐
- CSS media queries 媒体查询
最近在做一些页面打印时的特殊处理接触到了media queries,想系统学习一下,在MOZILLA DEVELOPER NETWORK看到一篇文章讲的很不错,结合自己的使用总结一下. CSS2/me ...
- 94. Binary Tree Inorder Traversal (Java)
Given a binary tree, return the inorder traversal of its nodes' values. Example: Input: [1,null,2,3] ...
- 什么是DDoS攻击?
本文转载自知道创宇云安全的知乎回答:DDoS 的肉鸡都是哪来的? 说到DDoS攻击,我们就不得不说“肉鸡”. “肉鸡”可谓是DDoS攻击的核心大杀器,作为一个要发起DDoS攻击的黑客来说,没有肉鸡就是 ...
- WebAPI跨域问题处理
1.按照https://dzone.com/articles/access-control-allow-origin-header-and-the-aspnet文章所述,在程序中配置允许跨域请求. 但 ...
- Linux下如何查看CPU型号、个数、核数、逻辑CPU数、位数、发行版本、内核信息、内存、服务器生产厂家
[原文链接]:http://blog.csdn.net/mdx20072419/article/details/7767809 http://blog.chinaunix.net/uid-224252 ...
- 4.pca与梯度上升法
(一)什么是pca pca,也就是主成分分析法(principal component analysis),主要是用来对数据集进行降维处理.举个最简单的例子,我要根据姓名.年龄.头发的长度.身高.体重 ...
- U-boot新手入门,烧写进mini2440
拿到一块开发板,首先就要找到它的资料,当然了,开发板的厂商或者代理商会提供资料,资料里会有你需要的. 比如我的这块mini2440,在友善之臂代理商提供的资料里面,就有我们这篇所需要的 把这个文件夹下 ...
- ZenCart通过Contact Us接收垃圾邮件的过滤方案
最近收到一些通过Contact Us进行垃圾外链群发的邮件,虽然可以通过在Contact Us增加验证码来解决,但不利于客户体验.所以我们可以通过简单的关键词过滤来实现,一般垃圾外链都含有“[url= ...
- java8学习之groupingByConcurrent与partioningBy源码分析
在上一次[http://www.cnblogs.com/webor2006/p/8387656.html]中对于Collectors.groupingBy()方法进行了完整的分析之后,接着继续来分析一 ...
- 使用ajax向服务端发送Form中的数据
前端代码: <form action="" id="myFormUpdate"> <p>宠物名称: <input type=&qu ...