前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >进程的基本概念

进程的基本概念

作者头像
DragonKingZhu
发布2020-03-24 16:59:09
5380
发布2020-03-24 16:59:09
举报

本系列文章将重点学习分析进程的相关内容,包括进程的基本概念,进程的创建,fork,vfork,clone等系统调用是如何创建进程的,linux内核是如何描述一个进程的,以及进程的调度算法学习,比如CFS调度算法等相关内容。

其中前提的准备工作:

  • 以linux5.0内核代码为基础学习
  • 以ARM64架构来实践

学习过程中会通过实践+阅读内核源代码+图文并茂的方式来呈现进程管理的相关内容。

为什么要学习进程管理?

当自己写了一个简单的hello_world程序后,然后打印在控制台。

难道大家没有思考如下的几个问题嘛

  • 这个Hello_world程序时如何运行起来的?
  • 当系统中有8个cpu时,此hello_world是运行在那个cpu上?
  • 在运行程序期间,程序会暂停吗?还是一直在占用cpu?
  • 当系统负载比较高的时候,程序会在各个cpu之间做负载均衡吗?
  • 自己写的程序会不会被抢占调度等
  • 等等

当学习过进程管理后,你就很清楚的知道,自己写的程序时如何运行的? 何时被CPU调度的? 何时放弃CPU? 何时睡眠等。所以我们必须翻阅这座山。

什么是程序?

程序就可以简单的理解是程序语言为了完成某种功能的一个数据集合。

代码语言:javascript
复制
#include <stdio.h>
 
int main()
{
    printf("Hello_world!\n");
    return 0;
}

比如上述的hello_world程序,就是由C语言组成的一个数据的集合。

将这段程序编译,然后在计算机中运行起来之后就变为了进程

进程 = 程序 + 执行

什么是进程?

在大学的操作系统中肯定学过这样一段话:进程是最小资源分配的基本单位,线程是调度的基本单位,也称线程为轻量级进程。

比如对于上面的hello_world程序,如果想要在操作系统中运行就必须给分配相应的资源,比如内存资源。比如通过如下命令获取子程序的各个段

可以看到一个进程如果要正在运行起来,操作系统肯定会给它分配各个段,比如上面的代码段,数据段,堆栈段等等

总结:

  • 进程是一段执行中的程序
  • 进程是一个有生命的个体,既然有生命就会存在生命周期。
  • 进程运行起来是由代码段,数据段,堆栈段等信息组成

进程的生命周期

上面说过进程是一个有生命的个体,既然有生命就存在创建,活动,停止,销毁等状态。

上面的图片描述一个5种常见的状态

  • 当一个进程刚创建完毕的时候它的状态是就绪状态,这个时候就是等待CPU的调度。
  • 当CPU从就绪队列中选择刚创建的新进程,这时候此进程的状态就是运行状态
  • 当此进程由于要等待外部事件的产生,比如等待键盘输入,串口信号等,就会让出CPU,进入到祖塞态
  • 当在祖塞态的进程收到外部的时间发生,然后唤醒此进程,此进程又会进去到就绪队里中等待CPU选择
  • 当一个进程在CPU上运行完毕后,比如调用exit函数,则会释放资源到退出状态。

以上都是通用操作系统的基本概念,我们来看下linux中是如何描述一个进程的。

Linux中的task_struct结构

linux内核中使用task_struct结构来描述一个进程

代码语言:javascript
复制
struct task_struct {
     
    volatile long            state;           
 
    void                *stack;
     
    int                on_rq;
 
    int                prio;
    int                static_prio;
    int                normal_prio;
    unsigned int            rt_priority;
 
    const struct sched_class    *sched_class;
    struct sched_entity        se;
    struct sched_rt_entity        rt;
     
    unsigned int            policy;
    int                nr_cpus_allowed;
    cpumask_t            cpus_allowed;
     
    struct mm_struct        *mm;
    struct mm_struct        *active_mm;
     
    int                exit_state;
    int                exit_code;
    int                exit_signal;
 
 
    pid_t                pid;
    pid_t                tgid;
     
    char                comm[TASK_COMM_LEN];
 
    /* Filesystem information: */
    struct fs_struct        *fs;
 
    /* Open file information: */
    struct files_struct        *files;
 
    /* Namespaces: */
    struct nsproxy            *nsproxy;
 
    /* Signal handlers: */
    struct signal_struct        *signal;
 
    ......
}

此结构体在5.0的内核中长达600多行,这里我们只挑一些重点的字段说下。

  • state: 进程的状态
  • exit_state: 进程退出的状态
代码语言:javascript
复制
/* Used in tsk->state: */
#define TASK_RUNNING            0x0000
#define TASK_INTERRUPTIBLE        0x0001
#define TASK_UNINTERRUPTIBLE        0x0002
#define __TASK_STOPPED            0x0004
#define __TASK_TRACED            0x0008
/* Used in tsk->exit_state: */
#define EXIT_DEAD            0x0010
#define EXIT_ZOMBIE            0x0020
#define EXIT_TRACE            (EXIT_ZOMBIE | EXIT_DEAD)
/* Used in tsk->state again: */
#define TASK_PARKED            0x0040
#define TASK_DEAD            0x0080
#define TASK_WAKEKILL            0x0100
#define TASK_WAKING            0x0200
#define TASK_NOLOAD            0x0400
#define TASK_NEW            0x0800
#define TASK_STATE_MAX            0x1000
  • prio, static_prio, normal_prio, rt_priority: 进程的优先级
  • sched_class, se:调度类,调度实体
  • cpus_allowed: cpu mask,运行此进程在那个CPU上运行
  • mm,active_mm:执行内存资源
  • pid,tgid:进程的标识符
  • comm: 进程的名字
  • fs:文件系统资源
  • files: 文件资源
  • signal:信号资源

上面说了进程是资源分配的基本单位,那一个进程中肯定包含着这个进程运行起来的资源,比如mm内存资源,fs文件系统资源,files文件资源,signal信号资源等。

Linux中的进程状态

上图是Linux中的经典的进程状态,增加了暂停和僵死两种状态,将祖塞状态分为TASK_INTERRUPTBLE(可中断)和TASK_UNINTERRUPTIBLE(不可中断)

  • 可中断和不可中断的区别是可中断可以通过信号唤醒,而不可中断必须要等待资源就位
  • 暂停状态相当于我们按下Ctrl+Z组合按键
  • 僵死状态其实是进程退出的一个临界状态,一般是看不到的。当子进程退出时,如果父进程没有给子进行“收棺验尸”,则子进程就变为了僵死进程。
  • 通过情况下,子进程以某种原因退出,父进程会通过waitpid来查看子进程的退出原因的。后面一小节会有僵死进程的专题来学习。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 为什么要学习进程管理?
  • 什么是程序?
  • 什么是进程?
  • 进程的生命周期
    • 以上都是通用操作系统的基本概念,我们来看下linux中是如何描述一个进程的。
    • Linux中的task_struct结构
    • Linux中的进程状态
    相关产品与服务
    负载均衡
    负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档