精华内容
下载资源
问答
  • CPU与核心进程和线程认识
    千次阅读
    2020-12-24 09:40:31

    CPU与核心

    物理核

    物理核数量 = cpu数(机子上装的cpu的数量)*每个cpu的核心数

    虚拟核

    所谓的4核8线程,4核指的是物理核心。通过超线程技术,用一个物理核模拟两个虚拟核,每个核两个线程,总数为8线程。

    在操作系统看来是8个核,但是实际上是4个物理核。

    通过超线程技术可以实现单个物理核实现线程级别的并行计算,但是比不上性能两个物理核。

    单核cpu和多核cpu

    都是一个cpu,不同的是每个cpu上的核心数

    多核cpu是多个单核cpu的替代方案,多核cpu减小了体积,同时也减少了功耗

    一个核心只能同时执行一个线程

    进程和线程

    理解

    进程是操作系统进行资源(包括cpu、内存、磁盘IO等)分配的最小单位

    线程是cpu调度和分配的基本单位

    我们打开的微信,浏览器都是一个进程

    进程可能有多个子任务,比如微信要接受消息,发送消息,这些子任务就是线程。

    资源分配给进程,线程共享进程资源。

    对比

    线程切换

    cpu给线程分配时间片(也就是分配给线程的时间),执行完时间片后会切换都另一个线程。

    切换之前会保存线程的状态,下次时间片再给这个线程时才能知道当前状态。

    从保存线程A的状态再到切换到线程B时,重新加载线程B的状态的这个过程就叫上下文切换。

    而上下切换时会消耗大量的cpu时间。

    线程开销

    上下文切换消耗

    线程创建和消亡的开销

    线程需要保存维持线程本地栈,会消耗内存

    串行,并发与并行

    串行

    多个任务,执行时一个执行完再执行另一个。

    比喻:吃完饭再看球赛。

    并发

    多个线程在单个核心运行,同一时间一个线程运行,系统不停切换线程,看起来像同时运行,实际上是线程不停切换。

    比喻: 一会跑去食厅吃饭,一会跑去客厅看球赛。

    并行

    每个线程分配给独立的核心,线程同时运行。

    比喻:一边吃饭一边看球赛。

    多核下线程数量选择

    计算密集型

    程序主要为复杂的逻辑判断和复杂的运算。

    cpu的利用率高,不用开太多的线程,开太多线程反而会因为线程切换时切换上下文而浪费资源。

    IO密集型

    程序主要为IO操作,比如磁盘IO(读取文件)和网络IO(网络请求)。

    因为IO操作会阻塞线程,cpu利用率不高,可以开多点线程,阻塞时可以切换到其他就绪线程,提高cpu利用率。

    总结

    提高性能的一种方式:提高硬件水平,处理速度或核心数。

    另一种方式:根据场景,合理设置线程数,软件上提高cpu利用率。

    更多相关内容
  • 【Linux】Linux进程简介及其五种状态

    万次阅读 2018-07-24 21:42:36
    由操作系统定义,并由操作系统所操控的一个特殊的数据结构实例叫做进程。它连接了用户代码,拥有代码运行所需的独立内存空间,在调度器的调度下使用分配给它的处理器时间片来运行。   进程及其私有内存空间 进程...

    由操作系统定义,并由操作系统所操控的一个特殊的数据结构实例叫做进程。它连接了用户代码,拥有代码运行所需的独立内存空间,在调度器的调度下使用分配给它的处理器时间片来运行。

     

    进程及其私有内存空间

    进程类似于UCOSIII中的任务,它也是用户应用程序可执行代码在系统中的一个运行过程。系统中用来表示进程身份和存在的也是控制块,只不过叫做进程控制块。进程与UCOSIII任务之间最重要的一个区别就是:进程具有自己的内存空间,进程的程序代码就运行在这个归自己所有的内存空间之中。当然,进程的控制块记录了进程的这个私有内存空间。

    在UCOSIII中提到,一个任务的组成部分:任务堆栈、任务控制块、任务代码。同样Linux的进程除了这三块,同时还需要进程自己的内存空间。一个典型的进程控制块如下图所示:

    进程控制块的成员mm就是指向进程内存控制块的指针,而这个进程内存控制块则关联了进程的虚拟空间结构和表示了它所占用的物理内存空间结构。

    所谓进程私有内存空间,就是系统使程序运行为程序分配的程序空间。保证程序具有私有空间的基础就是虚拟内存技术。系统把程序运行所需的物理内存页框地址映射成虚拟地址,并以页表的形式提供给了程序,从而使得程序只能通过页表运行于自己的物理空间而不会干扰到系统中的其它进程。

    结合前面关于Linux内存管理的讲解可知,Linux进程控制块中的mm成员如下图所示:

    文章参考:【Linux】Linux虚拟内存空间描述

    另外,由于Linux进程分为用户空间和内核空间两个部分,它有时运行于用户空间,有时运行于内核空间,因此为了保护各自的现场数据,一个进程还需要两个堆栈:用户堆栈和系统堆栈,如下图所示:

    最后区分一下进程和线程:在多任务系统中具有私有内存空间的正在运行的程序叫做进程,而没有私有内存空间的叫做线程。如此说来,其实UCOSIII的任务是划分到线程的。

     

    Linux进程的状态

    在Linux系统中,一个进程被创建之后,在系统中可以有下面5种状态。进程的当前状态记录在进程控制块的state成员中。

    就绪状态和运行状态

    就绪状态的状态标志state的值为TASK_RUNNING。此时,程序已被挂入运行队列,处于准备运行状态。一旦获得处理器使用权,即可进入运行状态。

    当进程获得处理器而运行时 ,state的值仍然为TASK_RUNNING,并不发生改变;但Linux会把一个专门用来指向当前运行任务的指针current指向它,以表示它是一个正在运行的进程。

    可中断等待状态

    状态标志state的值为TASK_INTERRUPTIBL。此时,由于进程未获得它所申请的资源而处在等待状态。一旦资源有效或者有唤醒信号,进程会立即结束等待而进入就绪状态。

    不可中断等待状态

    状态标志state的值为TASK_UNINTERRUPTIBL。此时,进程也处于等待资源状态。一旦资源有效,进程会立即进入就绪状态。这个等待状态与可中断等待状态的区别在于:处于TASK_UNINTERRUPTIBL状态的进程不能被信号量或者中断所唤醒,只有当它申请的资源有效时才能被唤醒。

    这个状态被应用在内核中某些场景中,比如当进程需要对磁盘进行读写,而此刻正在DMA中进行着数据到内存的拷贝,如果这时进程休眠被打断(比如强制退出信号)那么很可能会出现问题,所以这时进程就会处于不可被打断的状态下。

    停止状态

    状态标志state的值为TASK_STOPPED。当进程收到一个SIGSTOP信号后,就由运行状态进入停止状态,当受到一个SIGCONT信号时,又会恢复运行状态。这种状态主要用于程序的调试,又被叫做“暂停状态”、“挂起状态”。

    中止状态

    状态标志state的值为TASK_DEAD。进程因某种原因而中止运行,进程占有的所有资源将被回收,除了task_struct结构(以及少数资源)以外,并且系统对它不再予以理睬,所以这种状态也叫做“僵死状态”,进程成为僵尸进程。

    在进程的整个生命周期中,它可在5种状态之间转换。Linux进程5种状态之间的转换关系如下图所示:

    文章参考:Linux进程状态解析 之 R、S、D、T、Z、X (主要有三个状态)

    Linux有两类进程:一类是普通用户进程,它既可以在用户空间运行,又可通过系统调用进入内核空间,并在内核空间运行;另一类叫做内核进程,这种进程只能在内核空间运行。

     

    Linux的进程控制块

    在Linux中,线程、进程使用的是相同的核心数据结构。可以说,在Linux2.4的内核里只有进程,其中包含轻量进程(线程)。一个进程在核心中使用一个task_struct结构来表示,包含了大量描述该进程的信息。

    Linux系统中作为进程控制块(PCB)的数据结构叫做task_struct。这个进程控制块要负责记录和跟踪进程在系统中的全部信息。

    尽管task_struct数据结构庞大而复杂,但其成员可按功能分成一些组成部分。task_struct的数据结构应包含如下信息:

    • 进程的当前状态;
    • 调度信息:调度器需要知道这些信息,以便判断系统中进程的迫切度;
    • 进程标识:系统中每个进程都有一个进程标识pid;
    • 进程的通信信息:Linux支持经典的Unix IPC机制,如信号、管道和信号灯;支持系统V中的IPC机制,包括共享内存、信号灯和消息队列;
    • 进程与其他进程之间关系的信息:Linux中所有进程都是相互关联的。除了根进程外,所有进程都有一个父进程,也可能有子进程或者兄弟进程,所以每个进程的task_struct结构中要包含有指向其父进程、兄弟进程或子进程的指针;
    • 使用文件的信息:进程可自由地打开或关闭文件。进程的task_struct结构中包含一个指向文件系统及它所打开文件的指针;
    • 虚拟内存与物理内存关系的信息:所有进程都有自己的内存空间;
    • 计时器:核心需要记录进程的创建时间及其在其生命周期中消耗的CPU的时间;
    • 处理器中与进程有关的信息。

    Linux可以管理512个进程,每个进程的进程控制块指针都存放在一个数组中。为了使系统可快速访问正在运行的进程,Linux系统把当前运行进程的指针存放在指针变量current中。

    进程控制块task_struct的部分定义如下:

    struct task_struct {
    	volatile long state;	/* 进程的状态 */
    
    	unsigned long flags;	/* 与管理有关的状态信息 */
    
    	int prio, static_prio, normal_prio;        //优先级,静态优先级
    
    	struct list_head tasks;            //进程链表
    
    	struct list_head ptrace_children;
    	struct list_head ptrace_list;
    
    	struct mm_struct *mm, *active_mm;        //指向进程存储空间的指针
    
    	pid_t pid;                     //进程的pid
    	pid_t tgid;
    
    	struct task_struct *real_parent;     /* 真父进程指针 */
    	struct task_struct *parent;         /* 父进程指针 */
    
    	struct list_head children;	        /* 子进程链表 */
    	struct list_head sibling;	        /* 兄弟进程链表 */
    	struct task_struct *group_leader;	        /* threadgroup leader */
    
    	struct timespec start_time; 		/* monotonic time */
    	struct timespec real_start_time;	/* boot based time */
    
    	struct thread_struct thread;
    
            unsigned long rt_priority;            //实时优先级
    
    	struct fs_struct *fs;                //进程所在文件目录
    	struct files_struct *files;            //进程打开文件信息
        
            struct dentry *proc_dentry;            //proc文件的dentry
            struct backing_dev_info *backing_dev_info;
    
    	struct signal_struct *signal;                //信号
    	struct sighand_struct *sighand;
    
            ...
    
    };

    系统中把所有进程控制块组织为如下图所示的双向链表:

     

    展开全文
  • 什么是状态机?用C语言实现进程5状态模型

    千次阅读 多人点赞 2020-10-13 08:43:49
    一个健壮的状态机可以让你的程序,不论发生何种突发事件都不会突然进入一个不可预知的程序分支,本篇通过实现一个简单的进程5状态模型的状态机,让大家熟悉一下状态机的魅力。 定义 有限状态机(finite-state ...

    前言

    状态机在实际工作开发中应用非常广泛,在刚进入公司的时候,根据公司产品做流程图的时候,发现自己经常会漏了这样或那样的状态,导致整体流程会有问题,后来知道了状态机这样的东西,发现用这幅图就可以很清晰的表达整个状态的流转。

    一口君曾经做过很多网络协议模块,很多协议的开发都必须用到状态机;一个健壮的状态机可以让你的程序,不论发生何种突发事件都不会突然进入一个不可预知的程序分支。

    本篇通过C语言实现一个简单的进程5状态模型的状态机,让大家熟悉一下状态机的魅力。

    什么是状态机?

    定义

    状态机是有限状态自动机的简称,是现实事物运行规则抽象而成的一个数学模型。

    先来解释什么是“状态”( State )。现实事物是有不同状态的,例如一个LED等,就有 亮 和 灭两种状态。我们通常所说的状态机是有限状态机,也就是被描述的事物的状态的数量是有限个,例如LED灯的状态就是两个 亮和 灭。

    状态机,也就是 State Machine ,不是指一台实际机器,而是指一个数学模型。说白了,一般就是指一张状态转换图。

    举例

    以物理课学的灯泡图为例,就是一个最基本的小型状态机
    在这里插入图片描述

    可以画出以下的状态机图

    在这里插入图片描述
    这里就是两个状态:①灯泡亮,②灯泡灭
    如果打开开关,那么状态就会切换为 灯泡亮 。灯泡亮 状态下如果关闭开关,状态就会切换为 灯泡灭。

    状态机的全称是有限状态自动机,自动两个字也是包含重要含义的。给定一个状态机,同时给定它的当前状态以及输入,那么输出状态时可以明确的运算出来的。例如对于灯泡,给定初始状态灯泡灭 ,给定输入“打开开关”,那么下一个状态时可以运算出来的。

    四大概念

    下面来给出状态机的四大概念。

    1. State ,状态。一个状态机至少要包含两个状态。例如上面灯泡的例子,有 灯泡亮和 灯泡灭两个状态。

    2. Event ,事件。事件就是执行某个操作的触发条件或者口令。对于灯泡,“打开开关”就是一个事件。

    3. Action ,动作。事件发生以后要执行动作。例如事件是“打开开关”,动作是“开灯”。编程的时候,一个 Action 一般就对应一个函数。

    4. Transition ,变换。也就是从一个状态变化为另一个状态。例如“开灯过程”就是一个变换。

    状态机的应用

    状态机是一个对真实世界的抽象,而且是逻辑严谨的数学抽象,所以明显非常适合用在数字领域。可以应用到各个层面上,例如硬件设计,编译器设计,以及编程实现各种具体业务逻辑的时候。

    进程5状态模型

    进程管理是Linux五大子系统之一,非常重要,实际实现起来非常复杂,我们来看下进程是如何切换状态的。

    下图是进程的5状态模型:

    进程5状态模型
    关于该图简单介绍如下:

    1. 可运行态:当进程正在被CPU执行,或已经准备就绪随时可由调度程序执行,则称该进程为处于运行状态(running)。进程可以在内核态运行,也可以在用户态运行。当系统资源已经可用时,进程就被唤醒而进入准备运行状态,该状态称为就绪态。
    2. 浅度睡眠态(可中断):进程正在睡眠(被阻塞),等待资源到来是唤醒,也可以通过其他进程信号或时钟中断唤醒,进入运行队列。
    3. 深度睡眠态(不可中断):其和浅度睡眠基本类似,但有一点就是不可由其他进程信号或时钟中断唤醒。只有被使用wake_up()函数明确唤醒时才能转换到可运行的就绪状态。
    4. 暂停状态:当进程收到信号SIGSTOP、SIGTSTP、SIGTTIN或SIGTTOU时就会进入暂停状态。可向其发送SIGCONT信号让进程转换到可运行状态。
    5. 僵死状态:当进程已停止运行,但其父进程还没有询问其状态时,未释放PCB,则称该进程处于僵死状态。

    进程的状态就是按照这个状态图进行切换的。

    该状态流程有点复杂,因为我们目标只是实现一个简单的状态机,所以我们简化一下该状态机如下:
    简化的状态迁移图

    要想实现状态机,首先将该状态机转换成下面的状态迁移表。
    状态迁移表
    简要说明如下:
    假设当前进程处于running状态下,那么只有schedule事件发生之后,该进程才会产生状态的迁移,迁移到owencpu状态下,如果在此状态下发生了其他的事件,比如wake、wait_event都不会导致状态的迁移。

    如上图所示:

    1. 每一列表示一个状态,每一行对应一个事件。
    2. 该表是实现状态机的最核心的一个图,请读者详细对比该表和状态迁移图的的关系。
    3. 实际场景中,进程的切换会远比这个图复杂,好在众多大神都帮我们解决了这些复杂的问题,我们只需要站在巨人的肩膀上就可以了。

    实现

    根据状态迁移表,定义该状态机的状态如下:

    typedef enum {
      sta_origin=0,
      sta_running,
      sta_owencpu,
      sta_sleep_int,
      sta_sleep_unint
    }State;
    

    发生的事件如下:

    typedef enum{
      evt_fork=0,
      evt_sched,
      evt_wait,
      evt_wait_unint,
      evt_wake_up,
      evt_wake, 
    }EventID;
    

    不论是状态还是事件都可以根据实际情况增加调整。

    定义一个结构体用来表示当前状态转换信息:

    typedef struct {
      State curState;//当前状态
      EventID eventId;//事件ID
      State nextState;//下个状态
      CallBack action;//回调函数,事件发生后,调用对应的回调函数
    }StateTransform ; 
    

    事件回调函数:
    实际应用中不同的事件发生需要执行不同的action,就需要定义不同的函数,
    为方便起见,本例所有的事件都统一使用同一个回调函数。
    功能:
    打印事件发生后进程的前后状态,如果状态发生了变化,就调用对应的回调函数。

    void action_callback(void *arg)
    {
    	StateTransform *statTran = (StateTransform *)arg;
    	
    	if(statename[statTran->curState] == statename[statTran->nextState])
    	{
    		printf("invalid event,state not change\n");
    	}else{
    		printf("call back state from %s --> %s\n",
    			statename[statTran->curState],
    			statename[statTran->nextState]);
    	}
    }
    

    为各个状态定义迁移表数组:

    /*origin*/
    StateTransform stateTran_0[]={
    	{sta_origin,evt_fork,        sta_running,action_callback},
    	{sta_origin,evt_sched,       sta_origin,NULL},
    	{sta_origin,evt_wait,        sta_origin,NULL},
    	{sta_origin,evt_wait_unint,  sta_origin,NULL},
    	{sta_origin,evt_wake_up,     sta_origin,NULL},
    	{sta_origin,evt_wake,        sta_origin,NULL},
    }; 
    
    /*running*/
    StateTransform stateTran_1[]={
    	{sta_running,evt_fork,        sta_running,NULL},
    	{sta_running,evt_sched,       sta_owencpu,action_callback},
    	{sta_running,evt_wait,        sta_running,NULL},
    	{sta_running,evt_wait_unint,  sta_running,NULL},
    	{sta_running,evt_wake_up,     sta_running,NULL},
    	{sta_running,evt_wake,        sta_running,NULL},
    }; 
    /*owencpu*/
    StateTransform stateTran_2[]={
    	{sta_owencpu,evt_fork,        sta_owencpu,NULL},
    	{sta_owencpu,evt_sched,       sta_owencpu,NULL},
    	{sta_owencpu,evt_wait,        sta_sleep_int,action_callback},
    	{sta_owencpu,evt_wait_unint,  sta_sleep_unint,action_callback},
    	{sta_owencpu,evt_wake_up,     sta_owencpu,NULL},
    	{sta_owencpu,evt_wake,        sta_owencpu,NULL},
    }; 
    
    /*sleep_int*/
    StateTransform stateTran_3[]={
    	{sta_sleep_int,evt_fork,        sta_sleep_int,NULL},
    	{sta_sleep_int,evt_sched,       sta_sleep_int,NULL},
    	{sta_sleep_int,evt_wait,        sta_sleep_int,NULL},
    	{sta_sleep_int,evt_wait_unint,  sta_sleep_int,NULL},
    	{sta_sleep_int,evt_wake_up,     sta_sleep_int,NULL},
    	{sta_sleep_int,evt_wake,        sta_running,action_callback},
    }; 
    /*sleep_unint*/
    StateTransform stateTran_4[]={
    	{sta_sleep_unint,evt_fork,        sta_sleep_unint,NULL},
    	{sta_sleep_unint,evt_sched,       sta_sleep_unint,NULL},
    	{sta_sleep_unint,evt_wait,        sta_sleep_unint,NULL},
    	{sta_sleep_unint,evt_wait_unint,  sta_sleep_unint,NULL},
    	{sta_sleep_unint,evt_wake_up,     sta_running,action_callback},
    	{sta_sleep_unint,evt_wake,        sta_sleep_unint,NULL},
    }; 
    

    实现event发生函数:

    void event_happen(unsigned int event)
    功能:
    	根据发生的event以及当前的进程state,找到对应的StateTransform 结构体,并调用do_action()
    
    void do_action(StateTransform *statTran)
    功能:
    	根据结构体变量StateTransform,实现状态迁移,并调用对应的回调函数。
    
    #define STATETRANS(n)  (stateTran_##n)
    /*change state & call callback()*/
    void do_action(StateTransform *statTran)
    {
    	if(NULL == statTran)
    	{
    		perror("statTran is NULL\n");
    		return;
    	}
    	//状态迁移
    	globalState = statTran->nextState;
    	if(statTran->action != NULL)
    	{//调用回调函数
    		statTran->action((void*)statTran);
    	}else{
    		printf("invalid event,state not change\n");
    	}
    }
    void event_happen(unsigned int event)
    {
    	switch(globalState)
    	{
    		case sta_origin:
    			do_action(&STATETRANS(0)[event]);
    			break;
    		case sta_running:
    			do_action(&STATETRANS(1)[event]);
    			break;
    		case sta_owencpu:
    			do_action(&STATETRANS(2)[event]);	
    			break;
    		case sta_sleep_int:
    			do_action(&STATETRANS(3)[event]);	
    			break;
    		case sta_sleep_unint:
    			do_action(&STATETRANS(4)[event]);	
    			break;
    		default:
    			printf("state is invalid\n");
    			break;
    	}
    }
    

    测试程序:
    功能:

    1. 初始化状态机的初始状态为sta_origin;
    2. 创建子线程,每隔一秒钟显示当前进程状态;
    3. 事件发生顺序为:evt_fork–>evt_sched–>evt_sched–>evt_wait–>evt_wake。

    读者可以跟自己的需要,修改事件发生顺序,观察状态的变化。

    main.c

    /*显示当前状态*/
    void *show_stat(void *arg)
    {
    	int len;
    	char buf[64]={0};
    	
    	while(1)
    	{
    		sleep(1);
    		printf("cur stat:%s\n",statename[globalState]);
    	}	
    }
    void main(void)
    {
    	init_machine();
    	//创建子线程,子线程主要用于显示当前状态
    	pthread_create(&pid, NULL,show_stat, NULL);
    
    	sleep(5);
    	event_happen(evt_fork);
    
    	sleep(5);
    	event_happen(evt_sched);
    	sleep(5);
    	event_happen(evt_sched);
    	sleep(5);
    	event_happen(evt_wait);
    	sleep(5);
    	event_happen(evt_wake);
    	
    }
    
    

    运行结果:
    在这里插入图片描述
    由结果可知:

    evt_fork-->evt_sched-->evt_sched-->evt_wait-->evt_wake
    

    该事件发生序列对应的状态迁移顺序为:

    origen-->running-->owencpu-->owencpu-->sleep_int-->running
    

    完整代码请关注公众号:一口Linux,回复statmachine

    展开全文
  • 进程控制:七状态模型

    千次阅读 2021-03-06 16:16:49
    首先,进程的七状态模型,分为:创造、就绪、执行、堵塞、终止、挂起就绪、挂起阻塞。 进程 进程没有一个规定的定义,一般定义为: 进程是程序的一次执行 进程是一个程序及其数据在处理机上顺序执行时所发生的活动 ...

    在这里插入图片描述
    首先,进程的七状态模型,分为:创造、就绪、执行、堵塞、终止、挂起就绪、挂起阻塞。

    进程

    进程没有一个规定的定义,一般定义为:

    • 进程是程序的一次执行
    • 进程是一个程序及其数据在处理机上顺序执行时所发生的活动
    • 进程时具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位

    在引入进程实体的概念后,我们可以把传统OS中的进程定义为:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。

    进程的特征

    • 动态性:进程的实质是进程实体的执行过程。
    • 并发性:多个进程同存于内存中,且能在一段时间内同时运行。
    • 独立性:能独立运行、独立获得资源和独立接受调度的基本单位。
    • 异步性:不可预知的速度向前推进。

    进程控制块

    是操作系统核心中一种数据结构,主要表示进程状态。

    进程控制块的作用

    使一个在多道程序环境下不能独立运行的程序(含数据),成为一个能独立运行的基本单位或与其它进程并发执行的进程。

    • 具体的说:
    • 作为独立运行基本单位的标志 —— 当一个程序配置了PCB后,就表示它已是一个能在多道程序环境下独立运行的、合法的基本单位。PCB已经成为了进程存在于系统中的唯一标志。
    • 能实现间断性运行方式 —— 有了PCB后,系统可以将终端进程的CPU现场信息存放在PCB中,供该进程在被调度时恢复CPU现场信息。
    • 提供进程管理所需要的信息 —— 当进程调度时、需要访问文件或I/O设备时,都需要借助PCB中资源清单的信息。
    • 提供进程调度所需要的信息 —— 进程调度时,需要提供优先级、等待时间和已执行时间等。
    • 实现与其他进程的同步与通信 —— 进程同步,需要相应的用于同步的信号量,还需要具有用于实现进程通信的区域或通信队列指针等。

    进程控制块中的信息

    • 进程标识符:用于唯一标识一个进程。分为两种标识符:
      • 外部标识符:为了方便用户(进程)对进程的访问,
      • 内部标识符:为了方便系统对进程的使用,唯一的数字标识符
    • 处理机状态:也称为处理机的上下文,主要是由处理机的各种寄存器中的内容组成的。这些寄存器主要包括:
      • 通用寄存器 —— 又称为用户可视寄存器,是用户程序可以访问的,用于暂存信息,在大多数处理机中,由8~32个通用寄存器,在RISC结构的计算机中可超过100个。
      • 指令计数器 —— 其中存放要访问的下一条指令的地址。
      • 程序状态字PSW —— 含有状态信息,如:条件码、执行方式、中断屏蔽标志等
      • 用户栈指针 —— 指每个用户进程都有一个或若干个与之相关的系统栈,用于存放过程和系统调用参数及调用地址。栈指针指向该栈的栈顶。
    • 进程调度信息 :包括进程状态、进程优先级、进程调度所需的其他信息、事件。
    • 进程控制信息:程序和数据的地址、进程同步和通信机制、资源清单、链接指针。

    进程控制块的组织方式

    • 线性方式
    • 链接方式
    • 索引方式

    七状态模型

    进程创建

    引起进程创建的事件

    • 用户登录
    • 作业调度
    • 提供服务
    • 应用请求

    进程如何创建

    • 申请空白PCB
    • 为新进程分配其运行所需的资源
    • 初始化进程控制块:初始化标识信息、初始化处理机状态信息、初始化处理机控制信息。
    • 如果进程就绪队列能够接纳新进程,便将新进程插入就绪队列。

    进程终止

    引起进程终止的事件

    • 正常结束
    • 异常结束
      • 越界错
      • 保护错
      • 非法指令
      • 特权指令错
      • 运行超时
      • 等待超时
      • 算术运算错
      • I/O故障
    • 外界干扰
      • 操作员或操作系统干预
      • 父进程请求
      • 因父进程终止

    进程的终止过程

    • 根据被终止进程的标识符,从PCB集合中检索出该进程的PCB,从中读出该进程的状态。
    • 若处于执行状态,终止执行,调度标志改为真。
    • 若还有子孙进程,应将子孙进程都终止,以防他们称为不可控的进程。
    • 将资源归还给父进程,或系统。
    • 将被终止进程的PCB从所在队列中移除,等待其他程序调用。

    进程的阻塞与唤醒

    引起进程堵塞和唤起的事件

    • 向系统请求共享资源失败
    • 等待某种操作的完成
    • 新数据尚未到达
    • 等待新任务的到达

    进程堵塞的过程

    • 正在执行的进程,如果发生了上述某事件,进程便通过调用阻塞原语block将自己阻塞。
    • 可见,阻塞是进程自身的一种主动行为。
    • 进入block过程后,由于该进程还处于执行状态,所以应先立即停止执行,把进程控制块中的状态由"执行"改为阻塞,并将PCB插入阻塞队列。
    • 如果系统中设置了因不同事件而堵塞的多个堵塞队列,则应将本进程插入到具有相同事件的堵塞队列。
    • 最后,转调度程序进行重新调度,将处理机分配给另一就绪进程,并进行切换,保留被阻塞进程的处理机状态,按新进程的PCB中的处理机状态设置CPU的环境。

    进程唤醒过程

    • 当被阻塞进程所期待的事件发生时,由有关进程调用唤醒原语wakeup,将等待该事件的进程唤醒。
    • wakeup执行的过程是:首先把阻塞的进程从等待该事件的阻塞队列中移出,将其PCB中的现行状态由阻塞改为就绪,然后再将该PCB插入到就绪队列中。

    进程的挂起与激活

    进程的挂起过程

    • 当系统中出现了引起进程挂起的事件时,OS将利用挂起原语suspend将指定进程或处于阻塞状态的进程挂起。
    • suspend的执行过程时:首先检查被挂起进程的状态,若处于活动就绪状态,便将其改为静止就绪。
    • 对于活动阻塞状态的进程,则将之改为静止阻塞。
    • 为了方便用户或父进程考察该进程的运行情况,而把该进程的PCB复制到某指定的内存区域。
    • 最后,若被挂起进程正在执行,则转向调度程序重新调度。

    进程的激活过程

    • 当系统中发生激活过程的事件时,OS将利用激活原语active,将指定进程激活。
    • 激活原语先将进程从外存调入内存,检查该进程的现行状态。
    • 若是静止就绪,改为活动就绪。
    • 若是静止阻塞,改为活动阻塞。
    展开全文
  • Zabbix通过进程名监控进程状态配置详解 有时候我们只能通过进程名监控一个进程是否停掉了,因为有的进程并没有对外提供端口号,以下记录了下详细步骤,通过这个示例会学到很多zabbix核心配置相关的东西。 总的来说...
  • 学无止境环境线程的时间片分配线程的执行进程状态三个状态状态的迁移 环境 无特殊指明,本文基于linux 线程的时间片分配 对linux系统来说,用户创建进程后,CPU分配时间片的单位其实是按线程分的。假如你的程序里...
  • 如何杀掉D,Z状态进程

    千次阅读 2018-07-17 00:49:06
    original url: ... ... R- -可执行状态(运行状态)  只有在运行状态进程才有可能在CPU上运行,注意是可能,并不意味着进程一定在运行中。同一时刻可能有多个进程...
  • 3.3 多进程引起的基本问题 3.3.1 多个进程的组织与进程状态 操作系统要实现多进程的有序执行,首先就要解决如何组织这多个进程的问题。分析这多个进程之间的关系,如同学生排队打饭,等待着CPU的调度。那么显而易见...
  • 如何查看linux系统中的进程状态

    千次阅读 2018-12-24 17:42:19
    linux上进程有5种状态: 1. 运行(正在运行或在运行队列中等待) 2. 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号) 3. 不可中断(收到信号不唤醒和不可运行, 进程必须等待直到有中断发生) 4. 僵死(进程已终止, ...
  • 状态进程模型

    千次阅读 2017-11-27 16:45:27
    很容易想到,一个进程可以处于两种状态:运行态和非运行态。在非运行态中,有的进程在等待某些事件完成(如:I/O设备)后才能执行,称为阻塞或等待态,有的进程运行条件都已经满足,只差 CPU 资源就可以运行,称为...
  • 每当运行进程请求某个I/O操作时,短期调度程序就会保存进程的当前上下文(也称为PCB)并将其状态从运行状态更改为等待状态。 在此期间,进程处于等待状态; 短期调度程序从就绪队列中选择另一个进程并将CPU分配给此...
  • linux top进程状态D

    千次阅读 2017-05-10 20:42:00
    运行在KVM虚拟机里的一些进程突然出了问题,这些出了问题的进程无法用kill杀掉,使用ps可以看到这些进程处于D状态: [build@kbuild-john ~]$ ps -a -o pid,ppid,stat,command PID PPID STAT COMMAND 17009 1 Ds -...
  • 进程描述与进程状态变化:进程的定义、进程的组成、进程控制块、进程状态与结束、进程状态变化模型
  • • Edit 2017-03-20 • Updata 2017-03-20很容易想到,一个进程可以处于两种状态:运行态和非运行态。在非运行态中,有的进程在等待某些事件完成(如:I/O设备)后才能执行,称为阻塞或等待态,有的进程运行条件都...
  • CPU、核心进程、线程,串行、并发、并行
  • ps aux详解(进程状态说明)

    千次阅读 2015-11-23 16:17:01
    linux上进程有5种状态: 1. 运行(正在运行或在运行队列中等待) 2. 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号) 3. 不可中断(收到信号不唤醒和不可运行, 进程必须等待直到有中断发生) 4. 僵死(进程已...
  • 命令ps查看当前系统的进程状态

    千次阅读 2017-11-29 00:40:33
    命令ps查看当前系统的进程状态
  • 操作系统基本原理---进程管理

    千次阅读 2018-08-02 21:34:45
    处理机:计算机系统中存储程序和数据,...处理器cpu:中央处理器(Central Processing Unit)的缩写,即CPU,CPU是电脑中的核心配件,只有火柴盒那么大,几十张纸那么厚,但它却是一台计算机的运算核心和控制核心。...
  • Linux的进程有一种状态等待为TASK_UNINTERRUPTIBLE,称为D状态,该种状态进程不接收信号,只能通过wake_up唤醒。处于这种状态的情况有很多,例如mutex锁就可能会设置进程于该状态,有时候进程在等待某种IO资源就绪...
  • java 进程,线程及状态转换

    千次阅读 2016-05-28 20:25:22
    程序:一段静态的代码,一组指令的有序集合,它...它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而被撤消。反映了一个程序在一定的数据 集上运行的全部动态过程。通过进程控制块(PCB)唯
  • 这是作者的网络安全自学教程系列,主要是关于安全工具和...本文将分享Procmon软件基本用法及文件进程、注册表查看,这是一款微软推荐的系统监视工具,功能非常强大可用来检测恶意软件。基础性文章,希望对您有所帮助。
  • 线程、进程、多线程、多进程 和 多任务 小结

    千次阅读 多人点赞 2019-04-20 11:59:56
    1 进程 2 线程 3 多进程 4 多线程 5 线程与进程的关系 6 线程和进程的区别 7 进程的优缺点 7.1 进程的优点 7.2 进程的缺点 8 线程的优缺点 8.1 线程的优点 8.2 线程的缺点 9 多线程的优缺点 9.1 多线程...
  • TCP与UDP协议初步学习——网络环境中分布式进程通信的基本概念 一、单机系统中进程通信方法 进程进程通信是操作系统中最基本的概念,首先通过回忆操作系统课程中,关于单击系统中进程进程通信的问题描述: 1)...
  • 计算机理论/进程间通信

    千次阅读 2019-04-20 14:14:45
    进程间通信:   进程间通信(IPC, Inter-Process Communication)是指在不同的进程之间,相互传播或交换信息。IPC的方式通常有管道(包括无名管道和命名管道)消息队列、信号量、共享存储、socket、streams等… ...
  • linux下使用top命令查看系统运行状态进程运行状态 在linux下可以通过top命令来查系统运行状态进程运行状态,通过man查看top手册,top的解释是display Linux tasks,以前看到过一个另外的解释display top CPU ...
  • 文章目录什么是进程获取进程相关数据的 API进程 ID 什么是进程 在大学上操作系统课时,对进程的概念不太清楚,只能硬记:“进程是执行的代码”。 后来写的多了,认识到:“进程 = 执行的代码 + 数据 ”。 再过几年,...
  • Linux 下使用C++监测某一进程状态

    千次阅读 2017-07-31 00:00:18
    想要做一个简单的守护进程,就是监测系统中其它进程是否存在,若存在则认为该进程运行中,若不存在,则认为该进程挂掉。当然这样简单的判断很粗糙,先从简单的开始吧   例程转自博客:...
  • Linux任务管理与守护进程

    千次阅读 多人点赞 2022-02-06 12:59:49
    文章目录任务管理进程组概念作业概念会话概念相关操作前台进程&后台进程jobs、fg、bgps命令查看指定的选项守护进程 任务管理 进程组概念 每个进程除了有一个进程ID之外,还属于一个进程组,进程组是一个或多个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 299,659
精华内容 119,863
关键字:

进程基本的核心状态

友情链接: AT89S51.rar